// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Alert,
Platform,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import Video from 'react-native-video';
import RNFetchBlob from 'rn-fetch-blob';
import {intlShape} from 'react-intl';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
import VideoControls, {PLAYER_STATE} from 'app/components/video_controls';
import {DeviceTypes} from 'app/constants/';
import {getLocalFilePathFromFile} from 'app/utils/file';
import Downloader from './downloader.ios';
const {VIDEOS_PATH} = DeviceTypes;
export default class VideoPreview extends PureComponent {
static propTypes = {
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
file: PropTypes.object.isRequired,
onFullScreen: PropTypes.func.isRequired,
onSeeking: PropTypes.func,
theme: PropTypes.object.isRequired,
};
static contextTypes = {
intl: intlShape,
};
constructor(props) {
super(props);
let path = null;
const {file} = props;
if (file && file.data && file.data.localPath) {
path = file.data.localPath;
}
this.state = {
isLoading: true,
isFullScreen: false,
playerState: PLAYER_STATE.PAUSED,
paused: true,
currentTime: 0,
duration: 0,
path,
showDownloader: true,
};
}
componentWillMount() {
EventEmitter.on('stop-video-playback', this.stopPlayback);
this.initializeComponent();
}
componentWillUnmount() {
EventEmitter.off('stop-video-playback', this.stopPlayback);
}
async initializeComponent() {
const {file} = this.props;
const prefix = Platform.OS === 'android' ? 'file:/' : '';
const path = getLocalFilePathFromFile(VIDEOS_PATH, file);
const exist = await RNFetchBlob.fs.exists(`${prefix}${path}`);
if (exist) {
this.setState({path});
}
}
exitFullScreen = () => {
this.setState({isFullScreen: false});
this.props.onFullScreen(true);
};
enterFullScreen = () => {
this.setState({isFullScreen: true});
this.props.onFullScreen(false);
};
onDownloadSuccess = () => {
const {file} = this.props;
const path = file.data.localPath || getLocalFilePathFromFile(VIDEOS_PATH, file);
this.setState({showDownloader: false, path});
};
onEnd = () => {
if (this.state.isFullScreen) {
this.props.onFullScreen(true);
}
this.setState({playerState: PLAYER_STATE.ENDED, isFullScreen: false, paused: true});
};
onError = () => {
const {intl} = this.context;
Alert.alert(
intl.formatMessage({
id: 'mobile.video_playback.failed_title',
defaultMessage: 'Video playback failed',
}),
intl.formatMessage({
id: 'mobile.video_playback.failed_description',
defaultMessage: 'An error occurred while trying to play the video.\n',
}),
[{
text: intl.formatMessage({
id: 'mobile.server_upgrade.button',
defaultMessage: 'OK',
}),
}]
);
};
onFullScreen = () => {
if (this.state.isFullScreen) {
this.exitFullScreen();
} else {
this.enterFullScreen();
}
};
onLoad = (data) => {
this.setState({duration: data.duration, isLoading: false});
};
onLoadStart = () => {
this.setState({isLoading: true});
};
onPaused = () => {
this.setState({
paused: !this.state.paused,
playerState: this.state.paused ? PLAYER_STATE.PLAYING : PLAYER_STATE.PAUSED,
});
};
onProgress = (data) => {
if (this.state.isLoading || this.state.playerState !== PLAYER_STATE.PLAYING) {
return;
}
this.setState({currentTime: data.currentTime});
};
onReplay = () => {
if (this.refs.videoPlayer) {
this.setState({playerState: PLAYER_STATE.PLAYING, paused: false});
this.refs.videoPlayer.seek(0);
}
};
onSeek = (seek) => {
if (this.refs.videoPlayer) {
this.setState({currentTime: seek}, () => {
this.refs.videoPlayer.seek(seek);
});
}
};
stopPlayback = () => {
if (!this.state.paused) {
this.onPaused();
}
};
render() {
const {
deviceHeight,
deviceWidth,
file,
onSeeking,
theme,
} = this.props;
const {currentTime, duration, isFullScreen, isLoading, path, paused, playerState, showDownloader} = this.state;
if (!path) {
return (
);
}
return (
this.refs.controls.fadeInControls()}
>
);
}
}