From e0223c422b1ad56c93b9876b8109f41841534c67 Mon Sep 17 00:00:00 2001 From: Jeffrey Villamin Date: Mon, 30 Jul 2018 10:49:39 -1000 Subject: [PATCH 01/10] Update react-native-video to next version 2.1.0 which should have the iOS freezing fix --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 25cf4fa9..2aaa2901 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "react-native-orientation": "^3.1.0", "react-native-slider": "https://github.com/abbasfreestyle/react-native-slider.git", "react-native-vector-icons": "^4.4.2", - "react-native-video": "^2.0.0" + "react-native-video": "^2.1.0" }, "devDependencies": { "babel-cli": "^6.26.0", From 1b5de49cbba78cc8bbfce2d3fa0f39452eb54b47 Mon Sep 17 00:00:00 2001 From: Jeffrey Villamin Date: Mon, 30 Jul 2018 11:06:50 -1000 Subject: [PATCH 02/10] Upgrade react-native-video to latest version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2aaa2901..3aa9c464 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "react-native-orientation": "^3.1.0", "react-native-slider": "https://github.com/abbasfreestyle/react-native-slider.git", "react-native-vector-icons": "^4.4.2", - "react-native-video": "^2.1.0" + "react-native-video": "^3.1.0" }, "devDependencies": { "babel-cli": "^6.26.0", From d21f7a97979ebaa89a7ac998506b441cee458f95 Mon Sep 17 00:00:00 2001 From: Jeffrey Villamin Date: Tue, 31 Jul 2018 17:58:53 -1000 Subject: [PATCH 03/10] Change three dot icon to close (x) --- components/TopBar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/TopBar.js b/components/TopBar.js index 23b2ddb0..fa67f849 100644 --- a/components/TopBar.js +++ b/components/TopBar.js @@ -62,8 +62,8 @@ const TopBar = (props) => { style={styles.more} onPress={() => onMorePress()} paddingRight - iconOff="more-horiz" - iconOn="more-horiz" + iconOff="close" + iconOn="close" theme={theme.more} size={25} /> From 07c379c78b9e472ad0a9dd8f0a5966184ebc86a4 Mon Sep 17 00:00:00 2001 From: Jeffrey Villamin Date: Tue, 31 Jul 2018 18:09:03 -1000 Subject: [PATCH 04/10] Remove need for logo prop --- components/Controls.js | 102 +++++++++++++++++++++-------------------- components/TopBar.js | 65 +++++++++++++------------- 2 files changed, 83 insertions(+), 84 deletions(-) diff --git a/components/Controls.js b/components/Controls.js index 9645c94c..f629c15a 100644 --- a/components/Controls.js +++ b/components/Controls.js @@ -1,18 +1,12 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { View, Animated, StyleSheet, TouchableWithoutFeedback as Touchable -} from 'react-native' -import { - PlayButton, - ControlBar, - Loading, - TopBar, - ProgressBar -} from './' +} from "react-native"; +import { PlayButton, ControlBar, Loading, TopBar, ProgressBar } from "./"; const styles = StyleSheet.create({ container: { @@ -22,39 +16,39 @@ const styles = StyleSheet.create({ flex: { flex: 1 } -}) +}); class Controls extends Component { constructor() { - super() + super(); this.state = { hideControls: false, seconds: 0, seeking: false - } - this.animControls = new Animated.Value(1) - this.scale = new Animated.Value(1) - this.progressbar = new Animated.Value(2) + }; + this.animControls = new Animated.Value(1); + this.scale = new Animated.Value(1); + this.progressbar = new Animated.Value(2); } componentDidMount() { - this.setTimer() + this.setTimer(); } componentWillUnmount() { - clearInterval(this.timer) + clearInterval(this.timer); } onSeek(pos) { - this.props.onSeek(pos) + this.props.onSeek(pos); if (!this.state.seeking) { - this.setState({ seeking: true }) + this.setState({ seeking: true }); } } onSeekRelease(pos) { - this.props.onSeekRelease(pos) - this.setState({ seeking: false, seconds: 0 }) + this.props.onSeekRelease(pos); + this.setState({ seeking: false, seconds: 0 }); } setTimer() { @@ -62,47 +56,52 @@ class Controls extends Component { switch (true) { case this.state.seeking: // do nothing - break + break; case this.props.paused: - if (this.state.seconds > 0) this.setState({ seconds: 0 }) - break + if (this.state.seconds > 0) this.setState({ seconds: 0 }); + break; case this.state.hideControls: - break + break; case this.state.seconds > 3: - this.hideControls() - break + this.hideControls(); + break; default: - this.setState({ seconds: this.state.seconds + 1 }) + this.setState({ seconds: this.state.seconds + 1 }); } - }, 1000) + }, 1000); } showControls() { this.setState({ hideControls: false }, () => { - this.progressbar.setValue(2) + this.progressbar.setValue(2); Animated.parallel([ Animated.timing(this.animControls, { toValue: 1, duration: 200 }), Animated.timing(this.scale, { toValue: 1, duration: 200 }) - ]).start() - }) + ]).start(); + }); } hideControls() { Animated.parallel([ Animated.timing(this.animControls, { toValue: 0, duration: 200 }), Animated.timing(this.scale, { toValue: 0.25, duration: 200 }) - ]).start(() => this.setState({ hideControls: true, seconds: 0 })) + ]).start(() => this.setState({ hideControls: true, seconds: 0 })); } hiddenControls() { - Animated.timing(this.progressbar, { toValue: 0, duration: 200 }).start() + Animated.timing(this.progressbar, { toValue: 0, duration: 200 }).start(); return ( this.showControls()}> - - + + - ) + ); } loading() { @@ -110,7 +109,7 @@ class Controls extends Component { - ) + ); } displayedControls() { @@ -128,13 +127,15 @@ class Controls extends Component { duration, theme, inlineOnly - } = this.props + } = this.props; - const { center, ...controlBar } = theme + const { center, ...controlBar } = theme; return ( this.hideControls()}> - + onMorePress()} theme={{ title: theme.title, more: theme.more }} /> - + this.props.togglePlay()} paused={paused} @@ -167,15 +170,15 @@ class Controls extends Component { /> - ) + ); } render() { - if (this.props.loading) return this.loading() + if (this.props.loading) return this.loading(); if (this.state.hideControls) { - return this.hiddenControls() + return this.hiddenControls(); } - return this.displayedControls() + return this.displayedControls(); } } @@ -196,8 +199,7 @@ Controls.propTypes = { currentTime: PropTypes.number.isRequired, duration: PropTypes.number.isRequired, title: PropTypes.string.isRequired, - logo: PropTypes.string.isRequired, theme: PropTypes.object.isRequired -} +}; -export { Controls } +export { Controls }; diff --git a/components/TopBar.js b/components/TopBar.js index fa67f849..1a0c1338 100644 --- a/components/TopBar.js +++ b/components/TopBar.js @@ -1,28 +1,23 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from "react"; +import PropTypes from "prop-types"; -import { - View, - StyleSheet, - Text, - Image -} from 'react-native' +import { View, StyleSheet, Text, Image } from "react-native"; -import LinearGradient from 'react-native-linear-gradient' -import { ToggleIcon } from './' -import { checkSource } from './utils' +import LinearGradient from "react-native-linear-gradient"; +import { ToggleIcon } from "./"; +import { checkSource } from "./utils"; -const backgroundColor = 'transparent' +const backgroundColor = "transparent"; const styles = StyleSheet.create({ container: { height: 35, - justifyContent: 'center' + justifyContent: "center" }, row: { - flexDirection: 'row', - alignSelf: 'center', - alignItems: 'center' + flexDirection: "row", + alignSelf: "center", + alignItems: "center" }, title: { flex: 1, @@ -36,20 +31,23 @@ const styles = StyleSheet.create({ height: 25, width: 25 } -}) +}); -const TopBar = (props) => { - const { - logo, - more, - title, - theme, - onMorePress - } = props +const TopBar = props => { + const { logo, more, title, theme, onMorePress } = props; return ( - + - { logo && } + {logo && ( + + )} { > {title} - { more && + {more && ( onMorePress()} @@ -67,18 +65,17 @@ const TopBar = (props) => { theme={theme.more} size={25} /> - } + )} - ) -} + ); +}; TopBar.propTypes = { title: PropTypes.string.isRequired, - logo: PropTypes.string.isRequired, more: PropTypes.bool.isRequired, onMorePress: PropTypes.func.isRequired, theme: PropTypes.object.isRequired -} +}; -export { TopBar } +export { TopBar }; From 02622f7560f57df99dd2b1d7e9352af0ecb8186b Mon Sep 17 00:00:00 2001 From: Jeffrey Villamin Date: Wed, 1 Aug 2018 20:53:35 -1000 Subject: [PATCH 05/10] Change default color to white to fix warnings in Android emulator" --- components/PlayButton.js | 30 ++- components/Time.js | 38 ++-- components/ToggleIcon.js | 38 ++-- components/Video.js | 423 +++++++++++++++++++++------------------ 4 files changed, 276 insertions(+), 253 deletions(-) diff --git a/components/PlayButton.js b/components/PlayButton.js index 7349d60c..412e463a 100644 --- a/components/PlayButton.js +++ b/components/PlayButton.js @@ -1,9 +1,9 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { View, StyleSheet, TouchableOpacity } from 'react-native' -import Icons from 'react-native-vector-icons/MaterialIcons' +import React from "react"; +import PropTypes from "prop-types"; +import { View, StyleSheet, TouchableOpacity } from "react-native"; +import Icons from "react-native-vector-icons/MaterialIcons"; -const backgroundColor = 'transparent' +const backgroundColor = "transparent"; const styles = StyleSheet.create({ playButton: { @@ -12,30 +12,28 @@ const styles = StyleSheet.create({ playContainer: { flex: 1, backgroundColor, - alignItems: 'center', - justifyContent: 'center' + alignItems: "center", + justifyContent: "center" } -}) +}); const PlayButton = props => ( - props.onPress()} - > + props.onPress()}> -) +); PlayButton.propTypes = { onPress: PropTypes.func.isRequired, paused: PropTypes.bool.isRequired, theme: PropTypes.string.isRequired -} +}; -export { PlayButton } +export { PlayButton }; diff --git a/components/Time.js b/components/Time.js index 01be9137..23c0ae46 100644 --- a/components/Time.js +++ b/components/Time.js @@ -1,46 +1,48 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { View, Text, StyleSheet } from 'react-native' +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { View, Text, StyleSheet } from "react-native"; -const backgroundColor = 'transparent' +const backgroundColor = "transparent"; const styles = StyleSheet.create({ container: { - alignItems: 'center', + alignItems: "center", backgroundColor, - justifyContent: 'center', + justifyContent: "center", padding: 10, minWidth: 60 } -}) +}); class Time extends Component { getTime(time) { // format the seconds saved into 00:00:00 - const secs = time % 60 - const s2 = (time - secs) / 60 - const mins = s2 % 60 - const hrs = (s2 - mins) / 60 - const hours = this.addZeros(hrs) > 0 ? `${this.addZeros(hrs)}:` : '' - return `${hours}${this.addZeros(mins)}:${this.addZeros(secs)}` + const secs = time % 60; + const s2 = (time - secs) / 60; + const mins = s2 % 60; + const hrs = (s2 - mins) / 60; + const hours = this.addZeros(hrs) > 0 ? `${this.addZeros(hrs)}:` : ""; + return `${hours}${this.addZeros(mins)}:${this.addZeros(secs)}`; } addZeros(time) { - return (time < 10) ? (`0${time}`) : time + return time < 10 ? `0${time}` : time; } render() { return ( - {this.getTime(parseInt(this.props.time, 10))} + + {this.getTime(parseInt(this.props.time, 10))} + - ) + ); } } Time.propTypes = { time: PropTypes.number.isRequired, theme: PropTypes.string.isRequired -} +}; -export { Time } +export { Time }; diff --git a/components/ToggleIcon.js b/components/ToggleIcon.js index 78451623..5c0b8544 100644 --- a/components/ToggleIcon.js +++ b/components/ToggleIcon.js @@ -1,19 +1,19 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { View, StyleSheet, TouchableOpacity } from 'react-native' -import Icons from 'react-native-vector-icons/MaterialIcons' +import React from "react"; +import PropTypes from "prop-types"; +import { View, StyleSheet, TouchableOpacity } from "react-native"; +import Icons from "react-native-vector-icons/MaterialIcons"; -const backgroundColor = 'transparent' +const backgroundColor = "transparent"; const styles = StyleSheet.create({ btnContainer: { - alignItems: 'center', + alignItems: "center", backgroundColor, - justifyContent: 'center' + justifyContent: "center" } -}) +}); -const ToggleIcon = (props) => { +const ToggleIcon = props => { const { paddingLeft, paddingRight, @@ -22,28 +22,26 @@ const ToggleIcon = (props) => { iconOff, theme, size - } = props + } = props; const padding = { paddingLeft: paddingLeft ? 10 : 0, paddingRight: paddingRight ? 5 : 0 - } + }; return ( - props.onPress()} - > + props.onPress()}> - ) -} + ); +}; ToggleIcon.propTypes = { onPress: PropTypes.func, @@ -54,7 +52,7 @@ ToggleIcon.propTypes = { size: PropTypes.number, paddingRight: PropTypes.bool, paddingLeft: PropTypes.bool -} +}; ToggleIcon.defaultProps = { onPress: undefined, @@ -62,6 +60,6 @@ ToggleIcon.defaultProps = { size: 25, paddingRight: false, paddingLeft: false -} +}; -export { ToggleIcon } +export { ToggleIcon }; diff --git a/components/Video.js b/components/Video.js index 258171b6..c6f7dfce 100644 --- a/components/Video.js +++ b/components/Video.js @@ -1,5 +1,5 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Text, StyleSheet, @@ -9,21 +9,21 @@ import { Animated, Image, Alert -} from 'react-native' -import VideoPlayer from 'react-native-video' -import KeepAwake from 'react-native-keep-awake' -import Orientation from 'react-native-orientation' -import Icons from 'react-native-vector-icons/MaterialIcons' -import { Controls } from './' -import { checkSource } from './utils' -const Win = Dimensions.get('window') -const backgroundColor = '#000' +} from "react-native"; +import VideoPlayer from "react-native-video"; +import KeepAwake from "react-native-keep-awake"; +import Orientation from "react-native-orientation"; +import Icons from "react-native-vector-icons/MaterialIcons"; +import { Controls } from "./"; +import { checkSource } from "./utils"; +const Win = Dimensions.get("window"); +const backgroundColor = "#000"; const styles = StyleSheet.create({ background: { backgroundColor, - justifyContent: 'center', - alignItems: 'center', + justifyContent: "center", + alignItems: "center", zIndex: 98 }, fullScreen: { @@ -35,25 +35,25 @@ const styles = StyleSheet.create({ height: undefined, zIndex: 99 } -}) +}); const defaultTheme = { - title: '#FFF', - more: '#FFF', - center: '#FFF', - fullscreen: '#FFF', - volume: '#FFF', - scrubberThumb: '#FFF', - scrubberBar: '#FFF', - seconds: '#FFF', - duration: '#FFF', - progress: '#FFF', - loading: '#FFF' -} + title: "#FFF", + more: "#FFF", + center: "#FFF", + fullscreen: "#FFF", + volume: "#FFF", + scrubberThumb: "#FFF", + scrubberBar: "#FFF", + seconds: "#FFF", + duration: "#FFF", + progress: "#FFF", + loading: "#FFF" +}; class Video extends Component { constructor(props) { - super(props) + super(props); this.state = { paused: !props.autoPlay, muted: false, @@ -65,55 +65,61 @@ class Video extends Component { currentTime: 0, seeking: false, renderError: false - } - this.animInline = new Animated.Value(Win.width * 0.5625) - this.animFullscreen = new Animated.Value(Win.width * 0.5625) - this.BackHandler = this.BackHandler.bind(this) - this.onRotated = this.onRotated.bind(this) + }; + this.animInline = new Animated.Value(Win.width * 0.5625); + this.animFullscreen = new Animated.Value(Win.width * 0.5625); + this.BackHandler = this.BackHandler.bind(this); + this.onRotated = this.onRotated.bind(this); } componentDidMount() { - Dimensions.addEventListener('change', this.onRotated) - BackHandler.addEventListener('hardwareBackPress', this.BackHandler) + Dimensions.addEventListener("change", this.onRotated); + BackHandler.addEventListener("hardwareBackPress", this.BackHandler); } componentWillUnmount() { - Dimensions.removeEventListener('change', this.onRotated) - BackHandler.removeEventListener('hardwareBackPress', this.BackHandler) + Dimensions.removeEventListener("change", this.onRotated); + BackHandler.removeEventListener("hardwareBackPress", this.BackHandler); } onLoadStart() { - this.setState({ paused: true, loading: true }) + this.setState({ paused: true, loading: true }); } onLoad(data) { - if (!this.state.loading) return - this.props.onLoad(data) - const { height, width } = data.naturalSize - const ratio = height === 'undefined' && width === 'undefined' ? - (9 / 16) : (height / width) - const inlineHeight = this.props.lockRatio ? - (Win.width / this.props.lockRatio) - : (Win.width * ratio) - this.setState({ - paused: !this.props.autoPlay, - loading: false, - inlineHeight, - duration: data.duration - }, () => { - Animated.timing(this.animInline, { toValue: inlineHeight, duration: 200 }).start() - this.props.onPlay(!this.state.paused) - if (!this.state.paused) { - KeepAwake.activate() - if (this.props.fullScreenOnly) { - this.setState({ fullScreen: true }, () => { - this.props.onFullScreen(this.state.fullScreen) - this.animToFullscreen(Win.height) - if (this.props.rotateToFullScreen) Orientation.lockToLandscape() - }) + if (!this.state.loading) return; + this.props.onLoad(data); + const { height, width } = data.naturalSize; + const ratio = + height === "undefined" && width === "undefined" ? 9 / 16 : height / width; + const inlineHeight = this.props.lockRatio + ? Win.width / this.props.lockRatio + : Win.width * ratio; + this.setState( + { + paused: !this.props.autoPlay, + loading: false, + inlineHeight, + duration: data.duration + }, + () => { + Animated.timing(this.animInline, { + toValue: inlineHeight, + duration: 200 + }).start(); + this.props.onPlay(!this.state.paused); + if (!this.state.paused) { + KeepAwake.activate(); + if (this.props.fullScreenOnly) { + this.setState({ fullScreen: true }, () => { + this.props.onFullScreen(this.state.fullScreen); + this.animToFullscreen(Win.height); + if (this.props.rotateToFullScreen) Orientation.lockToLandscape(); + }); + } } } - }) + ); } // onBuffer() { @@ -122,194 +128,218 @@ class Video extends Component { // } onEnd() { - this.props.onEnd() - const { loop } = this.props - if (!loop) this.pause() - this.onSeekRelease(0) + this.props.onEnd(); + const { loop } = this.props; + if (!loop) this.pause(); + this.onSeekRelease(0); this.setState({ currentTime: 0 }, () => { - if (!loop) this.controls.showControls() - }) + if (!loop) this.controls.showControls(); + }); } onRotated({ window: { width, height } }) { // Add this condition incase if inline and fullscreen options are turned on - if (this.props.inlineOnly) return - const orientation = width > height ? 'LANDSCAPE' : 'PORTRAIT' + if (this.props.inlineOnly) return; + const orientation = width > height ? "LANDSCAPE" : "PORTRAIT"; if (this.props.rotateToFullScreen) { - if (orientation === 'LANDSCAPE') { + if (orientation === "LANDSCAPE") { this.setState({ fullScreen: true }, () => { - this.animToFullscreen(height) - this.props.onFullScreen(this.state.fullScreen) - }) - return + this.animToFullscreen(height); + this.props.onFullScreen(this.state.fullScreen); + }); + return; } - if (orientation === 'PORTRAIT') { - this.setState({ - fullScreen: false, - paused: this.props.fullScreenOnly || this.state.paused - }, () => { - this.animToInline() - if (this.props.fullScreenOnly) this.props.onPlay(!this.state.paused) - this.props.onFullScreen(this.state.fullScreen) - }) - return + if (orientation === "PORTRAIT") { + this.setState( + { + fullScreen: false, + paused: this.props.fullScreenOnly || this.state.paused + }, + () => { + this.animToInline(); + if (this.props.fullScreenOnly) + this.props.onPlay(!this.state.paused); + this.props.onFullScreen(this.state.fullScreen); + } + ); + return; } } else { - this.animToInline() + this.animToInline(); } - if (this.state.fullScreen) this.animToFullscreen(height) + if (this.state.fullScreen) this.animToFullscreen(height); } onSeekRelease(percent) { - const seconds = percent * this.state.duration + const seconds = percent * this.state.duration; this.setState({ progress: percent, seeking: false }, () => { - this.player.seek(seconds) - }) + this.player.seek(seconds); + }); } onError(msg) { - this.props.onError(msg) - const { error } = this.props + this.props.onError(msg); + const { error } = this.props; this.setState({ renderError: true }, () => { - let type + let type; switch (true) { case error === false: - type = error - break - case typeof error === 'object': - type = Alert.alert(error.title, error.message, error.button, error.options) - break + type = error; + break; + case typeof error === "object": + type = Alert.alert( + error.title, + error.message, + error.button, + error.options + ); + break; default: - type = Alert.alert('Oops!', 'There was an error playing this video, please try again later.', [{ text: 'Close' }]) - break + type = Alert.alert( + "Oops!", + "There was an error playing this video, please try again later.", + [{ text: "Close" }] + ); + break; } - return type - }) + return type; + }); } BackHandler() { if (this.state.fullScreen) { this.setState({ fullScreen: false }, () => { - this.animToInline() - this.props.onFullScreen(this.state.fullScreen) - if (this.props.fullScreenOnly && !this.state.paused) this.togglePlay() - if (this.props.rotateToFullScreen) Orientation.lockToPortrait() + this.animToInline(); + this.props.onFullScreen(this.state.fullScreen); + if (this.props.fullScreenOnly && !this.state.paused) this.togglePlay(); + if (this.props.rotateToFullScreen) Orientation.lockToPortrait(); setTimeout(() => { - if (!this.props.lockPortraitOnFsExit) Orientation.unlockAllOrientations() - }, 1500) - }) - return true + if (!this.props.lockPortraitOnFsExit) + Orientation.unlockAllOrientations(); + }, 1500); + }); + return true; } - return false + return false; } pause() { - if (!this.state.paused) this.togglePlay() + if (!this.state.paused) this.togglePlay(); } play() { - if (this.state.paused) this.togglePlay() + if (this.state.paused) this.togglePlay(); } togglePlay() { this.setState({ paused: !this.state.paused }, () => { - this.props.onPlay(!this.state.paused) + this.props.onPlay(!this.state.paused); Orientation.getOrientation((e, orientation) => { - if (this.props.inlineOnly) return + if (this.props.inlineOnly) return; if (!this.state.paused) { if (this.props.fullScreenOnly && !this.state.fullScreen) { this.setState({ fullScreen: true }, () => { - this.props.onFullScreen(this.state.fullScreen) - const initialOrient = Orientation.getInitialOrientation() - const height = orientation !== initialOrient ? - Win.width : Win.height - this.animToFullscreen(height) - if (this.props.rotateToFullScreen) Orientation.lockToLandscape() - }) + this.props.onFullScreen(this.state.fullScreen); + const initialOrient = Orientation.getInitialOrientation(); + const height = + orientation !== initialOrient ? Win.width : Win.height; + this.animToFullscreen(height); + if (this.props.rotateToFullScreen) Orientation.lockToLandscape(); + }); } - KeepAwake.activate() + KeepAwake.activate(); } else { - KeepAwake.deactivate() + KeepAwake.deactivate(); } - }) - }) + }); + }); } toggleFS() { this.setState({ fullScreen: !this.state.fullScreen }, () => { Orientation.getOrientation((e, orientation) => { if (this.state.fullScreen) { - const initialOrient = Orientation.getInitialOrientation() - const height = orientation !== initialOrient ? - Win.width : Win.height - this.props.onFullScreen(this.state.fullScreen) - if (this.props.rotateToFullScreen) Orientation.lockToLandscape() - this.animToFullscreen(height) + const initialOrient = Orientation.getInitialOrientation(); + const height = orientation !== initialOrient ? Win.width : Win.height; + this.props.onFullScreen(this.state.fullScreen); + if (this.props.rotateToFullScreen) Orientation.lockToLandscape(); + this.animToFullscreen(height); } else { if (this.props.fullScreenOnly) { - this.setState({ paused: true }, () => this.props.onPlay(!this.state.paused)) + this.setState({ paused: true }, () => + this.props.onPlay(!this.state.paused) + ); } - this.props.onFullScreen(this.state.fullScreen) - if (this.props.rotateToFullScreen) Orientation.lockToPortrait() - this.animToInline() + this.props.onFullScreen(this.state.fullScreen); + if (this.props.rotateToFullScreen) Orientation.lockToPortrait(); + this.animToInline(); setTimeout(() => { - if (!this.props.lockPortraitOnFsExit) Orientation.unlockAllOrientations() - }, 1500) + if (!this.props.lockPortraitOnFsExit) + Orientation.unlockAllOrientations(); + }, 1500); } - }) - }) + }); + }); } animToFullscreen(height) { Animated.parallel([ Animated.timing(this.animFullscreen, { toValue: height, duration: 200 }), Animated.timing(this.animInline, { toValue: height, duration: 200 }) - ]).start() + ]).start(); } animToInline(height) { - const newHeight = height || this.state.inlineHeight + const newHeight = height || this.state.inlineHeight; Animated.parallel([ - Animated.timing(this.animFullscreen, { toValue: newHeight, duration: 100 }), - Animated.timing(this.animInline, { toValue: this.state.inlineHeight, duration: 100 }) - ]).start() + Animated.timing(this.animFullscreen, { + toValue: newHeight, + duration: 100 + }), + Animated.timing(this.animInline, { + toValue: this.state.inlineHeight, + duration: 100 + }) + ]).start(); } toggleMute() { - this.setState({ muted: !this.state.muted }) + this.setState({ muted: !this.state.muted }); } seek(percent) { - const currentTime = percent * this.state.duration - this.setState({ seeking: true, currentTime }) + const currentTime = percent * this.state.duration; + this.setState({ seeking: true, currentTime }); } seekTo(seconds) { - const percent = seconds / this.state.duration + const percent = seconds / this.state.duration; if (seconds > this.state.duration) { - throw new Error(`Current time (${seconds}) exceeded the duration ${this.state.duration}`) - return false + throw new Error( + `Current time (${seconds}) exceeded the duration ${this.state.duration}` + ); + return false; } - return this.onSeekRelease(percent) + return this.onSeekRelease(percent); } progress(time) { - const { currentTime } = time - const progress = currentTime / this.state.duration + const { currentTime } = time; + const progress = currentTime / this.state.duration; if (!this.state.seeking) { this.setState({ progress, currentTime }, () => { - this.props.onProgress(time) - }) + this.props.onProgress(time); + }); } } renderError() { - const { fullScreen } = this.state + const { fullScreen } = this.state; const inline = { height: this.animInline, - alignSelf: 'stretch' - } - const textStyle = { color: 'white', padding: 10 } + alignSelf: "stretch" + }; + const textStyle = { color: "white", padding: 10 }; return ( this.setState({ renderError: false })} /> - ) + ); } renderPlayer() { @@ -335,7 +365,7 @@ class Video extends Component { duration, inlineHeight, currentTime - } = this.state + } = this.state; const { url, @@ -353,40 +383,45 @@ class Video extends Component { inlineOnly, playInBackground, playWhenInactive - } = this.props + } = this.props; const inline = { height: inlineHeight, - alignSelf: 'stretch' - } + alignSelf: "stretch" + }; const setTheme = { ...defaultTheme, ...theme - } + }; return ( - ) + ); } render() { - if (this.state.renderError) return this.renderError() - return this.renderPlayer() + if (this.state.renderError) return this.renderError(); + return this.renderPlayer(); } } Video.propTypes = { - url: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]).isRequired, - placeholder: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]), - style: PropTypes.oneOfType([ - PropTypes.object, - PropTypes.number - ]), - error: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.object - ]), + url: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + style: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + error: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), loop: PropTypes.bool, autoPlay: PropTypes.bool, inlineOnly: PropTypes.bool, @@ -472,7 +497,7 @@ Video.propTypes = { title: PropTypes.string, theme: PropTypes.object, resizeMode: PropTypes.string -} +}; Video.defaultProps = { placeholder: undefined, @@ -498,9 +523,9 @@ Video.defaultProps = { volume: 1, lockRatio: undefined, logo: undefined, - title: '', + title: "", theme: defaultTheme, - resizeMode: 'contain' -} + resizeMode: "contain" +}; -export default Video +export default Video; From 33b7d41af2b82eb64029042087029acefb283af1 Mon Sep 17 00:00:00 2001 From: Jeffrey Villamin Date: Tue, 27 Nov 2018 20:15:53 -1000 Subject: [PATCH 06/10] Fix StatusBar hidden in fullscreen --- components/Video.js | 86 ++++++++++++++++++++++----------------------- package.json | 8 ++--- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/components/Video.js b/components/Video.js index c6f7dfce..9cf98f7b 100644 --- a/components/Video.js +++ b/components/Video.js @@ -1,5 +1,5 @@ -import React, { Component } from "react"; -import PropTypes from "prop-types"; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { Text, StyleSheet, @@ -9,21 +9,21 @@ import { Animated, Image, Alert -} from "react-native"; -import VideoPlayer from "react-native-video"; -import KeepAwake from "react-native-keep-awake"; -import Orientation from "react-native-orientation"; -import Icons from "react-native-vector-icons/MaterialIcons"; -import { Controls } from "./"; -import { checkSource } from "./utils"; -const Win = Dimensions.get("window"); -const backgroundColor = "#000"; +} from 'react-native'; +import VideoPlayer from 'react-native-video'; +import KeepAwake from 'react-native-keep-awake'; +import Orientation from 'react-native-orientation'; +import Icons from 'react-native-vector-icons/MaterialIcons'; +import { Controls } from './'; +import { checkSource } from './utils'; +const Win = Dimensions.get('window'); +const backgroundColor = '#000'; const styles = StyleSheet.create({ background: { backgroundColor, - justifyContent: "center", - alignItems: "center", + justifyContent: 'center', + alignItems: 'center', zIndex: 98 }, fullScreen: { @@ -38,17 +38,17 @@ const styles = StyleSheet.create({ }); const defaultTheme = { - title: "#FFF", - more: "#FFF", - center: "#FFF", - fullscreen: "#FFF", - volume: "#FFF", - scrubberThumb: "#FFF", - scrubberBar: "#FFF", - seconds: "#FFF", - duration: "#FFF", - progress: "#FFF", - loading: "#FFF" + title: '#FFF', + more: '#FFF', + center: '#FFF', + fullscreen: '#FFF', + volume: '#FFF', + scrubberThumb: '#FFF', + scrubberBar: '#FFF', + seconds: '#FFF', + duration: '#FFF', + progress: '#FFF', + loading: '#FFF' }; class Video extends Component { @@ -73,13 +73,13 @@ class Video extends Component { } componentDidMount() { - Dimensions.addEventListener("change", this.onRotated); - BackHandler.addEventListener("hardwareBackPress", this.BackHandler); + Dimensions.addEventListener('change', this.onRotated); + BackHandler.addEventListener('hardwareBackPress', this.BackHandler); } componentWillUnmount() { - Dimensions.removeEventListener("change", this.onRotated); - BackHandler.removeEventListener("hardwareBackPress", this.BackHandler); + Dimensions.removeEventListener('change', this.onRotated); + BackHandler.removeEventListener('hardwareBackPress', this.BackHandler); } onLoadStart() { @@ -91,7 +91,7 @@ class Video extends Component { this.props.onLoad(data); const { height, width } = data.naturalSize; const ratio = - height === "undefined" && width === "undefined" ? 9 / 16 : height / width; + height === 'undefined' && width === 'undefined' ? 9 / 16 : height / width; const inlineHeight = this.props.lockRatio ? Win.width / this.props.lockRatio : Win.width * ratio; @@ -140,16 +140,16 @@ class Video extends Component { onRotated({ window: { width, height } }) { // Add this condition incase if inline and fullscreen options are turned on if (this.props.inlineOnly) return; - const orientation = width > height ? "LANDSCAPE" : "PORTRAIT"; + const orientation = width > height ? 'LANDSCAPE' : 'PORTRAIT'; if (this.props.rotateToFullScreen) { - if (orientation === "LANDSCAPE") { + if (orientation === 'LANDSCAPE') { this.setState({ fullScreen: true }, () => { this.animToFullscreen(height); this.props.onFullScreen(this.state.fullScreen); }); return; } - if (orientation === "PORTRAIT") { + if (orientation === 'PORTRAIT') { this.setState( { fullScreen: false, @@ -186,7 +186,7 @@ class Video extends Component { case error === false: type = error; break; - case typeof error === "object": + case typeof error === 'object': type = Alert.alert( error.title, error.message, @@ -196,9 +196,9 @@ class Video extends Component { break; default: type = Alert.alert( - "Oops!", - "There was an error playing this video, please try again later.", - [{ text: "Close" }] + 'Oops!', + 'There was an error playing this video, please try again later.', + [{ text: 'Close' }] ); break; } @@ -337,9 +337,9 @@ class Video extends Component { const { fullScreen } = this.state; const inline = { height: this.animInline, - alignSelf: "stretch" + alignSelf: 'stretch' }; - const textStyle = { color: "white", padding: 10 }; + const textStyle = { color: 'white', padding: 10 }; return ( -