diff --git a/app/src/component/fileDownloadButton/view.js b/app/src/component/fileDownloadButton/view.js index 883d7b78..c7901fe1 100644 --- a/app/src/component/fileDownloadButton/view.js +++ b/app/src/component/fileDownloadButton/view.js @@ -7,14 +7,14 @@ class FileDownloadButton extends React.PureComponent { const { costInfo, fetchCostInfo, uri } = this.props; if (costInfo === undefined) { fetchCostInfo(uri); - } + } } - + componentWillReceiveProps(nextProps) { //this.checkAvailability(nextProps.uri); this.restartDownload(nextProps); } - + restartDownload(props) { const { downloading, fileInfo, uri, restartDownload } = props; @@ -28,7 +28,7 @@ class FileDownloadButton extends React.PureComponent { restartDownload(uri, fileInfo.outpoint); } } - + render() { const { fileInfo, @@ -36,6 +36,8 @@ class FileDownloadButton extends React.PureComponent { uri, purchaseUri, costInfo, + isPlayable, + onPlay, loading, doPause, style, @@ -46,7 +48,7 @@ class FileDownloadButton extends React.PureComponent { const progress = fileInfo && fileInfo.written_bytes ? fileInfo.written_bytes / fileInfo.total_bytes * 100 : 0, label = fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...'; - + return ( @@ -67,8 +69,11 @@ class FileDownloadButton extends React.PureComponent { NativeModules.Mixpanel.track('Purchase Uri', { Uri: uri }); } purchaseUri(uri); + if (isPlayable && onPlay) { + this.props.onPlay(); + } }}> - Download + {isPlayable ? 'Play' : 'Download'} ); } else if (fileInfo && fileInfo.download_path) { diff --git a/app/src/component/mediaPlayer/view.js b/app/src/component/mediaPlayer/view.js index 2b74661c..5e13674b 100644 --- a/app/src/component/mediaPlayer/view.js +++ b/app/src/component/mediaPlayer/view.js @@ -11,21 +11,21 @@ import { import Video from 'react-native-video'; import Icon from 'react-native-vector-icons/FontAwesome'; import FileItemMedia from '../fileItemMedia'; -import mediaPlayerStyle from '../../styles/mediaPlayer'; +import mediaPlayerStyle from '../../styles/mediaPlayer'; class MediaPlayer extends React.PureComponent { static ControlsTimeout = 3000; - + seekResponder = null; - + seekerWidth = 0; - + trackingOffset = 0; - + tracking = null; - + video = null; - + constructor(props) { super(props); this.state = { @@ -35,7 +35,7 @@ class MediaPlayer extends React.PureComponent { resizeMode: 'stretch', duration: 0.0, currentTime: 0.0, - paused: true, + paused: !props.autoPlay, fullscreenMode: false, areControlsVisible: true, controlsTimeout: -1, @@ -44,51 +44,51 @@ class MediaPlayer extends React.PureComponent { firstPlay: true }; } - + formatTime(time) { let str = ''; let minutes = 0, hours = 0, seconds = parseInt(time, 10); if (seconds > 60) { minutes = parseInt(seconds / 60, 10); seconds = seconds % 60; - + if (minutes > 60) { hours = parseInt(minutes / 60, 10); minutes = minutes % 60; } - + str = (hours > 0 ? this.pad(hours) + ':' : '') + this.pad(minutes) + ':' + this.pad(seconds); } else { str = '00:' + this.pad(seconds); } - + return str; } - + pad(value) { if (value < 10) { return '0' + String(value); } - + return value; } - + onLoad = (data) => { this.setState({ duration: data.duration }); if (this.props.onMediaLoaded) { - this.props.onMediaLoaded(); + this.props.onMediaLoaded(); } } - + onProgress = (data) => { this.setState({ currentTime: data.currentTime }); - + if (!this.state.seeking) { this.setSeekerPosition(this.calculateSeekerPosition()); } - + if (this.state.firstPlay) { if (NativeModules.Mixpanel) { const { uri } = this.props; @@ -98,13 +98,13 @@ class MediaPlayer extends React.PureComponent { this.hidePlayerControls(); } } - + clearControlsTimeout = () => { if (this.state.controlsTimeout > -1) { clearTimeout(this.state.controlsTimeout) } } - + showPlayerControls = () => { this.clearControlsTimeout(); if (!this.state.areControlsVisible) { @@ -112,7 +112,7 @@ class MediaPlayer extends React.PureComponent { } this.hidePlayerControls(); } - + hidePlayerControls() { const player = this; let timeout = setTimeout(() => { @@ -120,12 +120,12 @@ class MediaPlayer extends React.PureComponent { }, MediaPlayer.ControlsTimeout); player.setState({ controlsTimeout: timeout }); } - + togglePlay = () => { this.showPlayerControls(); this.setState({ paused: !this.state.paused }); } - + toggleFullscreenMode = () => { this.showPlayerControls(); const { onFullscreenToggled } = this.props; @@ -136,12 +136,12 @@ class MediaPlayer extends React.PureComponent { } }); } - + onEnd = () => { this.setState({ paused: true }); this.video.seek(0); } - + setSeekerPosition(position = 0) { position = this.checkSeekerPosition(position); this.setState({ seekerPosition: position }); @@ -149,7 +149,7 @@ class MediaPlayer extends React.PureComponent { this.setState({ seekerOffset: position }); } } - + checkSeekerPosition(val = 0) { const offset = this.getTrackingOffset(); if (val < offset) { @@ -157,10 +157,10 @@ class MediaPlayer extends React.PureComponent { } else if (val >= (offset + this.seekerWidth)) { return offset + this.seekerWidth; } - + return val; } - + seekTo(time = 0) { if (time > this.state.duration) { return; @@ -168,22 +168,22 @@ class MediaPlayer extends React.PureComponent { this.video.seek(time); this.setState({ currentTime: time }); } - + initSeeker() { this.seekResponder = PanResponder.create({ onStartShouldSetPanResponder: (evt, gestureState) => true, onMoveShouldSetPanResponder: (evt, gestureState) => true, - + onPanResponderGrant: (evt, gestureState) => { this.clearControlsTimeout(); this.setState({ seeking: true }); }, - + onPanResponderMove: (evt, gestureState) => { const position = this.state.seekerOffset + gestureState.dx; this.setSeekerPosition(position); }, - + onPanResponderRelease: (evt, gestureState) => { const time = this.getCurrentTimeForSeekerPosition(); if (time >= this.state.duration) { @@ -197,37 +197,37 @@ class MediaPlayer extends React.PureComponent { } }); } - + getTrackingOffset() { return this.state.fullscreenMode ? this.trackingOffset : 0; } - + getCurrentTimeForSeekerPosition() { return this.state.duration * (this.state.seekerPosition / this.seekerWidth); } - + calculateSeekerPosition() { if (this.state.fullscreenMode) { return this.getTrackingOffset() + (this.seekerWidth * this.getCurrentTimePercentage()); } return this.seekerWidth * this.getCurrentTimePercentage(); } - + getCurrentTimePercentage() { if (this.state.currentTime > 0) { return parseFloat(this.state.currentTime) / parseFloat(this.state.duration); } return 0; }; - + componentWillMount() { this.initSeeker(); } - + componentDidMount() { - + } - + componentWillUnmount() { this.clearControlsTimeout(); this.setState({ paused: true, fullscreenMode: false }); @@ -236,7 +236,7 @@ class MediaPlayer extends React.PureComponent { onFullscreenToggled(false); } } - + renderPlayerControls() { if (this.state.areControlsVisible) { return ( @@ -246,18 +246,18 @@ class MediaPlayer extends React.PureComponent { {this.state.paused && } {!this.state.paused && } - + {this.state.fullscreenMode && } {!this.state.fullscreenMode && } - + {this.formatTime(this.state.currentTime)} {this.formatTime(this.state.duration)} ); } - + return null; } @@ -273,10 +273,10 @@ class MediaPlayer extends React.PureComponent { styles.push(style); } } - + const trackingStyle = [mediaPlayerStyle.trackingControls, this.state.fullscreenMode ? mediaPlayerStyle.fullscreenTrackingControls : mediaPlayerStyle.containedTrackingControls]; - + return (