Audio component
This commit is contained in:
parent
35b41ea494
commit
178bb8eaff
|
@ -1,99 +1,53 @@
|
||||||
// import React from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
// import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
|
|
||||||
// import { connect } from 'react-redux';
|
|
||||||
// import Sound from 'react-native-sound';
|
|
||||||
|
|
||||||
// const styles = StyleSheet.create({
|
|
||||||
// container: {
|
|
||||||
// flex: 1,
|
|
||||||
// justifyContent: 'center'
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// @connect(state => ({
|
|
||||||
// server: state.server.server
|
|
||||||
// }))
|
|
||||||
// export default class Audio extends React.PureComponent {
|
|
||||||
// static propTypes = {
|
|
||||||
// file: PropTypes.object.isRequired,
|
|
||||||
// server: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
// constructor(props) {
|
|
||||||
// super(props);
|
|
||||||
// this.state = {
|
|
||||||
// paused: true,
|
|
||||||
// loading: true
|
|
||||||
// };
|
|
||||||
// const { file, server } = this.props;
|
|
||||||
// const tmp = 'https://s3.amazonaws.com/hanselminutes/hanselminutes_0001.mp3';
|
|
||||||
// const uri = tmp;
|
|
||||||
// this.sound = new Sound(uri, undefined, (error) => {
|
|
||||||
// if (error) {
|
|
||||||
// console.warn(error);
|
|
||||||
// } else {
|
|
||||||
// this.setState({ loading: false });
|
|
||||||
// // console.log('Playing sound');
|
|
||||||
// // sound.play(() => {
|
|
||||||
// // // Release when it's done so we're not using up resources
|
|
||||||
// // sound.release();
|
|
||||||
// // });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// onPress() {
|
|
||||||
// if (this.state.paused) {
|
|
||||||
// this.sound.play();
|
|
||||||
// } else {
|
|
||||||
// this.sound.pause();
|
|
||||||
// }
|
|
||||||
// this.setState({ paused: !this.state.paused });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // getCurrentTime() {
|
|
||||||
// // this.sound.getCurrentTime(seconds => console.warn(seconds));
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// render() {
|
|
||||||
// if (this.state.loading) {
|
|
||||||
// return <Text>Loading...</Text>;
|
|
||||||
// }
|
|
||||||
// // this.getCurrentTime();
|
|
||||||
// return (
|
|
||||||
// <TouchableOpacity
|
|
||||||
// style={styles.container}
|
|
||||||
// onPress={() => this.onPress()}
|
|
||||||
// >
|
|
||||||
// <Text>{this.state.paused ? 'Play' : 'Pause'}</Text>
|
|
||||||
// </TouchableOpacity>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { View, StyleSheet, TouchableOpacity, Image, Text } from 'react-native';
|
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Modal from 'react-native-modal';
|
import Video from 'react-native-video';
|
||||||
import VideoPlayer from 'react-native-video-controls';
|
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||||
|
import Slider from 'react-native-slider';
|
||||||
|
|
||||||
|
const SUPPORTED_TYPES = ['video/webm'];
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
height: 100,
|
flexDirection: 'row',
|
||||||
margin: 5
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: 50,
|
||||||
|
margin: 5,
|
||||||
|
backgroundColor: '#eee',
|
||||||
|
borderRadius: 6
|
||||||
},
|
},
|
||||||
modal: {
|
playPauseButton: {
|
||||||
margin: 0,
|
width: 50,
|
||||||
backgroundColor: '#000'
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderRightColor: '#ccc',
|
||||||
|
borderRightWidth: 1
|
||||||
},
|
},
|
||||||
image: {
|
playPauseIcon: {
|
||||||
|
color: '#ccc',
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
},
|
||||||
|
progressContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
width: null,
|
justifyContent: 'center',
|
||||||
height: null,
|
height: '100%',
|
||||||
resizeMode: 'contain'
|
marginHorizontal: 10
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: '#888',
|
||||||
|
fontSize: 10
|
||||||
|
},
|
||||||
|
currentTime: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
bottom: 2
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
position: 'absolute',
|
||||||
|
right: 0,
|
||||||
|
bottom: 2
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -111,39 +65,96 @@ export default class Audio extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
const { server, file, user } = this.props;
|
const { server, file, user } = this.props;
|
||||||
|
this.onLoad = this.onLoad.bind(this);
|
||||||
|
this.onProgress = this.onProgress.bind(this);
|
||||||
|
this.onEnd = this.onEnd.bind(this);
|
||||||
this.state = {
|
this.state = {
|
||||||
isVisible: false,
|
currentTime: 0,
|
||||||
|
duration: 0,
|
||||||
|
paused: true,
|
||||||
uri: `${ server }${ file.audio_url }?rc_uid=${ user.id }&rc_token=${ user.token }`
|
uri: `${ server }${ file.audio_url }?rc_uid=${ user.id }&rc_token=${ user.token }`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleModal() {
|
onLoad(data) {
|
||||||
this.setState({
|
this.setState({ duration: data.duration });
|
||||||
isVisible: !this.state.isVisible
|
}
|
||||||
|
|
||||||
|
onProgress(data) {
|
||||||
|
if (data.currentTime < this.state.duration) {
|
||||||
|
this.setState({ currentTime: data.currentTime });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEnd() {
|
||||||
|
this.setState({ paused: true, currentTime: 0 });
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this.player.seek(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCurrentTime() {
|
||||||
|
return this.formatTime(this.state.currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDuration() {
|
||||||
|
return this.formatTime(this.state.duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatTime(time = 0) {
|
||||||
|
time = Math.min(
|
||||||
|
Math.max(time, 0),
|
||||||
|
this.state.duration
|
||||||
|
);
|
||||||
|
const formattedMinutes = Math.floor(time / 60).toFixed(0).padStart(2, 0);
|
||||||
|
const formattedSeconds = Math.floor(time % 60).toFixed(0).padStart(2, 0);
|
||||||
|
return `${ formattedMinutes }:${ formattedSeconds }`;
|
||||||
|
}
|
||||||
|
|
||||||
|
isTypeSupported() {
|
||||||
|
return SUPPORTED_TYPES.indexOf(this.props.file.audio_type) === -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
togglePlayPause() {
|
||||||
|
this.setState({ paused: !this.state.paused });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isVisible, uri } = this.state;
|
const { uri, paused } = this.state;
|
||||||
return (
|
return (
|
||||||
<View>
|
<View style={styles.container}>
|
||||||
|
<Video
|
||||||
|
ref={(ref) => {
|
||||||
|
this.player = ref;
|
||||||
|
}}
|
||||||
|
source={{ uri }}
|
||||||
|
onLoad={this.onLoad}
|
||||||
|
onProgress={this.onProgress}
|
||||||
|
onEnd={this.onEnd}
|
||||||
|
paused={paused}
|
||||||
|
repeat={false}
|
||||||
|
/>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.container}
|
style={styles.playPauseButton}
|
||||||
onPress={() => this.toggleModal()}
|
onPress={() => this.togglePlayPause()}
|
||||||
>
|
>
|
||||||
<Text>AUDIO</Text>
|
{
|
||||||
|
paused ? <Icon name='play-arrow' size={50} style={styles.playPauseIcon} />
|
||||||
|
: <Icon name='pause' size={47} style={styles.playPauseIcon} />
|
||||||
|
}
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<Modal
|
<View style={styles.progressContainer}>
|
||||||
isVisible={isVisible}
|
<Text style={[styles.label, styles.currentTime]}>{this.getCurrentTime()}</Text>
|
||||||
style={styles.modal}
|
<Text style={[styles.label, styles.duration]}>{this.getDuration()}</Text>
|
||||||
supportedOrientations={['portrait', 'landscape']}
|
<Slider
|
||||||
>
|
value={this.state.currentTime}
|
||||||
<VideoPlayer
|
maximumValue={this.state.duration}
|
||||||
source={{ uri }}
|
minimumValue={0}
|
||||||
onBack={() => this.toggleModal()}
|
animateTransitions
|
||||||
disableVolume
|
thumbTintColor='#ccc'
|
||||||
|
onValueChange={value => this.setState({ currentTime: value })}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12175,6 +12175,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-3.0.1.tgz",
|
||||||
"integrity": "sha1-DiPbMC0Du0o/KNwHLcryqaEXjtg="
|
"integrity": "sha1-DiPbMC0Du0o/KNwHLcryqaEXjtg="
|
||||||
},
|
},
|
||||||
|
"react-native-slider": {
|
||||||
|
"version": "0.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-slider/-/react-native-slider-0.11.0.tgz",
|
||||||
|
"integrity": "sha512-jV9K87eu9uWr0uJIyrSpBLnCKvVlOySC2wynq9TFCdV9oGgjt7Niq8Q1A8R8v+5GHsuBw/s8vEj1AAkkUi+u+w==",
|
||||||
|
"requires": {
|
||||||
|
"prop-types": "15.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-native-sound": {
|
"react-native-sound": {
|
||||||
"version": "0.10.4",
|
"version": "0.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.10.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.10.4.tgz",
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
"react-native-modal": "^4.1.1",
|
"react-native-modal": "^4.1.1",
|
||||||
"react-native-optimized-flatlist": "^1.0.3",
|
"react-native-optimized-flatlist": "^1.0.3",
|
||||||
"react-native-push-notification": "^3.0.1",
|
"react-native-push-notification": "^3.0.1",
|
||||||
|
"react-native-slider": "^0.11.0",
|
||||||
"react-native-sound": "^0.10.4",
|
"react-native-sound": "^0.10.4",
|
||||||
"react-native-svg": "^6.0.0",
|
"react-native-svg": "^6.0.0",
|
||||||
"react-native-svg-image": "^2.0.1",
|
"react-native-svg-image": "^2.0.1",
|
||||||
|
|
Loading…
Reference in New Issue