From ae0f230dbe36cb95c3fe39e22687d69599185ad5 Mon Sep 17 00:00:00 2001 From: Pete Cook Date: Sat, 17 Aug 2019 20:10:20 +0100 Subject: [PATCH] Lint fixes --- package.json | 1 + src/Player.js | 49 ++- src/Preview.js | 5 + src/ReactPlayer.js | 37 ++- src/demo/App.js | 492 +++++++++++++++------------- src/players/DailyMotion.js | 13 + src/players/Facebook.js | 11 + src/players/FilePlayer.js | 37 ++- src/players/Mixcloud.js | 12 + src/players/SoundCloud.js | 12 + src/players/Streamable.js | 13 + src/players/Twitch.js | 11 + src/players/Vimeo.js | 15 + src/players/Wistia.js | 14 + src/players/YouTube.js | 15 + src/preload.js | 2 +- src/props.js | 8 +- src/singlePlayer.js | 8 + src/utils.js | 6 +- test/Player.js | 38 +-- test/ReactPlayer/instanceMethods.js | 2 +- test/ReactPlayer/render.js | 2 +- test/players/FilePlayer.js | 55 ++-- test/players/Streamable.js | 2 + test/players/Twitch.js | 1 + test/players/YouTube.js | 1 + 26 files changed, 554 insertions(+), 308 deletions(-) diff --git a/package.json b/package.json index 0ea88d42..879c8abe 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "clean": "rimraf lib demo coverage", "start": "webpack-dev-server --config webpack/config.babel.js", "lint": "standard --verbose | snazzy", + "lint:fix": "standard --fix", "test": "cross-env NODE_ENV=test ava", "test:coverage": "cross-env NODE_ENV=test nyc ava", "test:codecov": "nyc report --reporter=json && codecov -f coverage/coverage-final.json", diff --git a/src/Player.js b/src/Player.js index f1ddc41a..fbcdab48 100644 --- a/src/Player.js +++ b/src/Player.js @@ -22,6 +22,7 @@ export default class Player extends Component { this.player.load(this.props.url) this.progress() } + componentWillUnmount () { clearTimeout(this.progressTimeout) clearTimeout(this.durationCheckTimeout) @@ -33,6 +34,7 @@ export default class Player extends Component { } this.mounted = false } + componentWillReceiveProps (nextProps) { // Invoke player methods based on incoming props const { url, playing, volume, muted, playbackRate, pip, loop, activePlayer } = this.props @@ -79,22 +81,27 @@ export default class Player extends Component { this.player.setLoop(nextProps.loop) } } + getDuration () { if (!this.isReady) return null return this.player.getDuration() } + getCurrentTime () { if (!this.isReady) return null return this.player.getCurrentTime() } + getSecondsLoaded () { if (!this.isReady) return null return this.player.getSecondsLoaded() } + getInternalPlayer = (key) => { if (!this.player) return null return this.player[key] } + progress = () => { if (this.props.url && this.player && this.isReady) { const playedSeconds = this.getCurrentTime() || 0 @@ -119,6 +126,7 @@ export default class Player extends Component { } this.progressTimeout = setTimeout(this.progress, this.props.progressFrequency || this.props.progressInterval) } + seekTo (amount, type) { // When seeking before player is ready, store value and seek later if (!this.isReady && amount !== 0) { @@ -139,7 +147,8 @@ export default class Player extends Component { } this.player.seekTo(amount) } - onReady = () => { + + handleReady = () => { if (!this.mounted) return this.isReady = true this.isLoading = false @@ -154,9 +163,10 @@ export default class Player extends Component { } else if (playing) { this.player.play() } - this.onDurationCheck() + this.handleDurationCheck() } - onPlay = () => { + + handlePlay = () => { this.isPlaying = true this.isLoading = false const { onStart, onPlay, playbackRate } = this.props @@ -172,15 +182,17 @@ export default class Player extends Component { this.seekTo(this.seekOnPlay) this.seekOnPlay = null } - this.onDurationCheck() + this.handleDurationCheck() } - onPause = (e) => { + + handlePause = (e) => { this.isPlaying = false if (!this.isLoading) { this.props.onPause(e) } } - onEnded = () => { + + handleEnded = () => { const { activePlayer, loop, onEnded } = this.props if (activePlayer.loopOnEnded && loop) { this.seekTo(0) @@ -190,11 +202,13 @@ export default class Player extends Component { onEnded() } } - onError = (...args) => { + + handleError = (...args) => { this.isLoading = false this.props.onError(...args) } - onDurationCheck = () => { + + handleDurationCheck = () => { clearTimeout(this.durationCheckTimeout) const duration = this.getDuration() if (duration) { @@ -203,19 +217,22 @@ export default class Player extends Component { this.onDurationCalled = true } } else { - this.durationCheckTimeout = setTimeout(this.onDurationCheck, 100) + this.durationCheckTimeout = setTimeout(this.handleDurationCheck, 100) } } - onLoaded = () => { + + handleLoaded = () => { // Sometimes we know loading has stopped but onReady/onPlay are never called // so this provides a way for players to avoid getting stuck this.isLoading = false } + ref = player => { if (player) { this.player = player } } + render () { const Player = this.props.activePlayer if (!Player) { @@ -225,12 +242,12 @@ export default class Player extends Component { ) } diff --git a/src/Preview.js b/src/Preview.js index fa398f7c..a2477970 100644 --- a/src/Preview.js +++ b/src/Preview.js @@ -7,19 +7,23 @@ export default class Preview extends Component { state = { image: null } + componentDidMount () { this.mounted = true this.fetchImage(this.props) } + componentWillReceiveProps (nextProps) { const { url, light } = this.props if (url !== nextProps.url || light !== nextProps.light) { this.fetchImage(nextProps) } } + componentWillUnmount () { this.mounted = false } + fetchImage ({ url, light }) { if (typeof light === 'string') { this.setState({ image: light }) @@ -35,6 +39,7 @@ export default class Preview extends Component { } }) } + render () { const { onClick } = this.props const { image } = this.state diff --git a/src/ReactPlayer.js b/src/ReactPlayer.js index cddf8cd2..cd116c0c 100644 --- a/src/ReactPlayer.js +++ b/src/ReactPlayer.js @@ -16,41 +16,48 @@ export default class ReactPlayer extends Component { static addCustomPlayer = player => { customPlayers.push(player) } + static removeCustomPlayers = () => { customPlayers = [] } + static displayName = 'ReactPlayer' static propTypes = propTypes static defaultProps = defaultProps static canPlay = url => { - for (let Player of [ ...customPlayers, ...players ]) { + for (const Player of [...customPlayers, ...players]) { if (Player.canPlay(url)) { return true } } return false } + static canEnablePIP = url => { - for (let Player of [ ...customPlayers, ...players ]) { + for (const Player of [...customPlayers, ...players]) { if (Player.canEnablePIP && Player.canEnablePIP(url)) { return true } } return false } + config = getConfig(this.props, defaultProps, true) state = { showPreview: !!this.props.light } + componentDidMount () { if (this.props.progressFrequency) { const message = 'ReactPlayer: %cprogressFrequency%c is deprecated, please use %cprogressInterval%c instead' console.warn(message, 'font-weight: bold', '', 'font-weight: bold', '') } } + shouldComponentUpdate (nextProps, nextState) { return !isEqual(this.props, nextProps) || !isEqual(this.state, nextState) } + componentWillUpdate (nextProps) { const { light } = this.props this.config = getConfig(nextProps, defaultProps) @@ -61,37 +68,46 @@ export default class ReactPlayer extends Component { this.setState({ showPreview: false }) } } - onClickPreview = () => { + + handleClickPreview = () => { this.setState({ showPreview: false }) } + showPreview = () => { this.setState({ showPreview: true }) } + getDuration = () => { if (!this.player) return null return this.player.getDuration() } + getCurrentTime = () => { if (!this.player) return null return this.player.getCurrentTime() } + getSecondsLoaded = () => { if (!this.player) return null return this.player.getSecondsLoaded() } + getInternalPlayer = (key = 'player') => { if (!this.player) return null return this.player.getInternalPlayer(key) } + seekTo = (fraction, type) => { if (!this.player) return null this.player.seekTo(fraction, type) } - onReady = () => { + + handleReady = () => { this.props.onReady(this) } + getActivePlayer (url) { - for (let Player of [ ...customPlayers, ...players ]) { + for (const Player of [...customPlayers, ...players]) { if (Player.canPlay(url)) { return Player } @@ -99,12 +115,15 @@ export default class ReactPlayer extends Component { // Fall back to FilePlayer if nothing else can play the URL return FilePlayer } + wrapperRef = wrapper => { this.wrapper = wrapper } + activePlayerRef = player => { this.player = player } + renderActivePlayer (url, activePlayer) { if (!url) return null return ( @@ -114,10 +133,11 @@ export default class ReactPlayer extends Component { ref={this.activePlayerRef} config={this.config} activePlayer={activePlayer} - onReady={this.onReady} + onReady={this.handleReady} /> ) } + sortPlayers (a, b) { // Retain player order to prevent weird iframe behaviour when switching players if (a && b) { @@ -125,6 +145,7 @@ export default class ReactPlayer extends Component { } return 0 } + render () { const { url, controls, style, width, height, light, wrapper: Wrapper } = this.props const showPreview = this.state.showPreview && url @@ -132,8 +153,8 @@ export default class ReactPlayer extends Component { const activePlayer = this.getActivePlayer(url) const renderedActivePlayer = this.renderActivePlayer(url, activePlayer) const preloadPlayers = renderPreloadPlayers(url, controls, this.config) - const players = [ renderedActivePlayer, ...preloadPlayers ].sort(this.sortPlayers) - const preview = + const players = [renderedActivePlayer, ...preloadPlayers].sort(this.sortPlayers) + const preview = return ( {showPreview ? preview : players} diff --git a/src/demo/App.js b/src/demo/App.js index a07161af..e841ddc0 100644 --- a/src/demo/App.js +++ b/src/demo/App.js @@ -33,6 +33,7 @@ class App extends Component { playbackRate: 1.0, loop: false } + load = url => { this.setState({ url, @@ -41,81 +42,102 @@ class App extends Component { pip: false }) } - playPause = () => { + + handlePlayPause = () => { this.setState({ playing: !this.state.playing }) } - stop = () => { + + handleStop = () => { this.setState({ url: null, playing: false }) } - toggleControls = () => { + + handleToggleControls = () => { const url = this.state.url this.setState({ controls: !this.state.controls, url: null }, () => this.load(url)) } - toggleLight = () => { + + handleToggleLight = () => { this.setState({ light: !this.state.light }) } - toggleLoop = () => { + + handleToggleLoop = () => { this.setState({ loop: !this.state.loop }) } - setVolume = e => { + + handleVolumeChange = e => { this.setState({ volume: parseFloat(e.target.value) }) } - toggleMuted = () => { + + handleToggleMuted = () => { this.setState({ muted: !this.state.muted }) } - setPlaybackRate = e => { + + handleSetPlaybackRate = e => { this.setState({ playbackRate: parseFloat(e.target.value) }) } - togglePIP = () => { + + handleTogglePIP = () => { this.setState({ pip: !this.state.pip }) } - onPlay = () => { + + handlePlay = () => { console.log('onPlay') this.setState({ playing: true }) } - onEnablePIP = () => { + + handleEnablePIP = () => { console.log('onEnablePIP') this.setState({ pip: true }) } - onDisablePIP = () => { + + handleDisablePIP = () => { console.log('onDisablePIP') this.setState({ pip: false }) } - onPause = () => { + + handlePause = () => { console.log('onPause') this.setState({ playing: false }) } - onSeekMouseDown = e => { + + handleSeekMouseDown = e => { this.setState({ seeking: true }) } - onSeekChange = e => { + + handleSeekChange = e => { this.setState({ played: parseFloat(e.target.value) }) } - onSeekMouseUp = e => { + + handleSeekMouseUp = e => { this.setState({ seeking: false }) this.player.seekTo(parseFloat(e.target.value)) } - onProgress = state => { + + handleProgress = state => { console.log('onProgress', state) // We only want to update time slider if we are not currently seeking if (!this.state.seeking) { this.setState(state) } } - onEnded = () => { + + handleEnded = () => { console.log('onEnded') this.setState({ playing: this.state.loop }) } - onDuration = (duration) => { + + handleDuration = (duration) => { console.log('onDuration', duration) this.setState({ duration }) } - onClickFullscreen = () => { + + handleClickFullscreen = () => { screenfull.request(findDOMNode(this.player)) } + renderLoadButton = (url, label) => { return ( ) } + ref = player => { this.player = player } + render () { const { url, playing, controls, light, volume, muted, loop, played, loaded, duration, playbackRate, pip } = this.state const SEPARATOR = ' ยท ' @@ -151,229 +175,233 @@ class App extends Component { muted={muted} onReady={() => console.log('onReady')} onStart={() => console.log('onStart')} - onPlay={this.onPlay} - onEnablePIP={this.onEnablePIP} - onDisablePIP={this.onDisablePIP} - onPause={this.onPause} + onPlay={this.handlePlay} + onEnablePIP={this.handleEnablePIP} + onDisablePIP={this.handleDisablePIP} + onPause={this.handlePause} onBuffer={() => console.log('onBuffer')} onSeek={e => console.log('onSeek', e)} - onEnded={this.onEnded} + onEnded={this.handleEnded} onError={e => console.log('onError', e)} - onProgress={this.onProgress} - onDuration={this.onDuration} + onProgress={this.handleProgress} + onDuration={this.handleDuration} /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controls - - - - {light && - - } - {ReactPlayer.canEnablePIP(url) && - - } -
Speed - - - -
Seek - -
Volume - -
- - - -   Requires player reload -
- - - -
- - - -
- - - -
Played
Loaded
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Controls + + + + {light && + } + {ReactPlayer.canEnablePIP(url) && + } +
Speed + + + +
Seek + +
Volume + +
+ + + +   Requires player reload +
+ + + +
+ + + +
+ + + +
Played
Loaded
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
YouTube - {this.renderLoadButton('https://www.youtube.com/watch?v=oUFJJNQGwhk', 'Test A')} - {this.renderLoadButton('https://www.youtube.com/watch?v=jNgP6d9HraI', 'Test B')} - {this.renderLoadButton('https://www.youtube.com/playlist?list=PLDEcUiPhzbjI217qs5KgMvbvx6-fgY_Al', 'Playlist')} -
SoundCloud - {this.renderLoadButton('https://soundcloud.com/miami-nights-1984/accelerated', 'Test A')} - {this.renderLoadButton('https://soundcloud.com/tycho/tycho-awake', 'Test B')} -
Facebook - {this.renderLoadButton('https://www.facebook.com/facebook/videos/10153231379946729/', 'Test A')} - {this.renderLoadButton('https://www.facebook.com/FacebookDevelopers/videos/10152454700553553/', 'Test B')} -
Vimeo - {this.renderLoadButton('https://vimeo.com/90509568', 'Test A')} - {this.renderLoadButton('https://vimeo.com/169599296', 'Test B')} -
Twitch - {this.renderLoadButton('https://www.twitch.tv/videos/106400740', 'Test A')} - {this.renderLoadButton('https://www.twitch.tv/videos/12783852', 'Test B')} - {this.renderLoadButton('https://www.twitch.tv/kronovi', 'Test C')} -
Streamable - {this.renderLoadButton('https://streamable.com/moo', 'Test A')} - {this.renderLoadButton('https://streamable.com/ifjh', 'Test B')} -
Wistia - {this.renderLoadButton('https://home.wistia.com/medias/e4a27b971d', 'Test A')} - {this.renderLoadButton('https://home.wistia.com/medias/29b0fbf547', 'Test B')} -
DailyMotion - {this.renderLoadButton('https://www.dailymotion.com/video/x5e9eog', 'Test A')} - {this.renderLoadButton('https://www.dailymotion.com/video/x61xx3z', 'Test B')} -
Mixcloud - {this.renderLoadButton('https://www.mixcloud.com/mixcloud/meet-the-curators/', 'Test A')} - {this.renderLoadButton('https://www.mixcloud.com/mixcloud/mixcloud-curates-4-mary-anne-hobbs-in-conversation-with-dan-deacon/', 'Test B')} -
Files - {this.renderLoadButton('http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', 'mp4')} - {this.renderLoadButton('http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv', 'ogv')} - {this.renderLoadButton('http://clips.vorwaerts-gmbh.de/big_buck_bunny.webm', 'webm')} - {this.renderLoadButton('https://storage.googleapis.com/media-session/elephants-dream/the-wires.mp3', 'mp3')} - {this.renderLoadButton(MULTIPLE_SOURCES, 'Multiple')} - {this.renderLoadButton('https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8', 'HLS (m3u8)')} - {this.renderLoadButton('http://dash.edgesuite.net/envivio/EnvivioDash3/manifest.mpd', 'DASH (mpd)')} -
Custom URL - { this.urlInput = input }} type='text' placeholder='Enter URL' /> - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
YouTube + {this.renderLoadButton('https://www.youtube.com/watch?v=oUFJJNQGwhk', 'Test A')} + {this.renderLoadButton('https://www.youtube.com/watch?v=jNgP6d9HraI', 'Test B')} + {this.renderLoadButton('https://www.youtube.com/playlist?list=PLDEcUiPhzbjI217qs5KgMvbvx6-fgY_Al', 'Playlist')} +
SoundCloud + {this.renderLoadButton('https://soundcloud.com/miami-nights-1984/accelerated', 'Test A')} + {this.renderLoadButton('https://soundcloud.com/tycho/tycho-awake', 'Test B')} +
Facebook + {this.renderLoadButton('https://www.facebook.com/facebook/videos/10153231379946729/', 'Test A')} + {this.renderLoadButton('https://www.facebook.com/FacebookDevelopers/videos/10152454700553553/', 'Test B')} +
Vimeo + {this.renderLoadButton('https://vimeo.com/90509568', 'Test A')} + {this.renderLoadButton('https://vimeo.com/169599296', 'Test B')} +
Twitch + {this.renderLoadButton('https://www.twitch.tv/videos/106400740', 'Test A')} + {this.renderLoadButton('https://www.twitch.tv/videos/12783852', 'Test B')} + {this.renderLoadButton('https://www.twitch.tv/kronovi', 'Test C')} +
Streamable + {this.renderLoadButton('https://streamable.com/moo', 'Test A')} + {this.renderLoadButton('https://streamable.com/ifjh', 'Test B')} +
Wistia + {this.renderLoadButton('https://home.wistia.com/medias/e4a27b971d', 'Test A')} + {this.renderLoadButton('https://home.wistia.com/medias/29b0fbf547', 'Test B')} +
DailyMotion + {this.renderLoadButton('https://www.dailymotion.com/video/x5e9eog', 'Test A')} + {this.renderLoadButton('https://www.dailymotion.com/video/x61xx3z', 'Test B')} +
Mixcloud + {this.renderLoadButton('https://www.mixcloud.com/mixcloud/meet-the-curators/', 'Test A')} + {this.renderLoadButton('https://www.mixcloud.com/mixcloud/mixcloud-curates-4-mary-anne-hobbs-in-conversation-with-dan-deacon/', 'Test B')} +
Files + {this.renderLoadButton('http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', 'mp4')} + {this.renderLoadButton('http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv', 'ogv')} + {this.renderLoadButton('http://clips.vorwaerts-gmbh.de/big_buck_bunny.webm', 'webm')} + {this.renderLoadButton('https://storage.googleapis.com/media-session/elephants-dream/the-wires.mp3', 'mp3')} + {this.renderLoadButton(MULTIPLE_SOURCES, 'Multiple')} + {this.renderLoadButton('https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8', 'HLS (m3u8)')} + {this.renderLoadButton('http://dash.edgesuite.net/envivio/EnvivioDash3/manifest.mpd', 'DASH (mpd)')} +
Custom URL + { this.urlInput = input }} type='text' placeholder='Enter URL' /> + +

State

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
url - {(url instanceof Array ? 'Multiple' : url) || 'null'} -
playing{playing ? 'true' : 'false'}
volume{volume.toFixed(3)}
played{played.toFixed(3)}
loaded{loaded.toFixed(3)}
duration
elapsed
remaining
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
url + {(url instanceof Array ? 'Multiple' : url) || 'null'} +
playing{playing ? 'true' : 'false'}
volume{volume.toFixed(3)}
played{played.toFixed(3)}
loaded{loaded.toFixed(3)}
duration
elapsed
remaining