|
@@ -1,4 +1,4 @@
|
|
|
-import React, { useState, useEffect, useRef, useMemo } from 'react';
|
|
|
+import React, { useState, useEffect, useRef, useMemo, useContext } from 'react';
|
|
|
import {
|
|
|
View,
|
|
|
Text,
|
|
@@ -22,6 +22,8 @@ import PlayerControls from './PlayerControls';
|
|
|
import PlayerContents from './PlayerContents';
|
|
|
import PlayerHeader from './PlayerHeader';
|
|
|
import { getInset } from 'react-native-safe-area-view';
|
|
|
+import Video from 'react-native-video';
|
|
|
+import { PlayerDispatchContext, PlayerStateContext } from './PlayerReducer';
|
|
|
|
|
|
const { width, height } = Dimensions.get('window');
|
|
|
const statusBarHeight = getStatusBarHeight(true);
|
|
@@ -299,240 +301,296 @@ export default props => {
|
|
|
}, []);
|
|
|
|
|
|
useEffect(() => {
|
|
|
- return () => {};
|
|
|
- });
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ playerDispatch({type:'currentTime', setCurrentTime: 0});
|
|
|
+ };
|
|
|
+ },[]);
|
|
|
|
|
|
const slideUp = () => {};
|
|
|
+
|
|
|
+ const player = useRef(null);
|
|
|
+
|
|
|
+ const playerDispatch = useContext(PlayerDispatchContext);
|
|
|
+ const { uri, paused, muted } = useContext(PlayerStateContext);
|
|
|
+ const playerOnBuffer = (data) => {
|
|
|
+ //console.log(data)
|
|
|
+ }
|
|
|
+ const playerOnError = (e) => {
|
|
|
+ console.log(e);
|
|
|
+ }
|
|
|
+ const playerOnLoad = (data) => {
|
|
|
+ //console.log(data.duration)
|
|
|
+ playerDispatch({type:'paused', setPaused:false});
|
|
|
+ playerDispatch({type:'duration', setDuraton: Math.floor(data.duration)});
|
|
|
+ }
|
|
|
+ const playerOnProgress = (data) => {
|
|
|
+ //console.log(data.currentTime)
|
|
|
+ playerDispatch({type:'currentTime', setCurrentTime: data.currentTime});
|
|
|
+ }
|
|
|
+ const onLoadStart = () => {
|
|
|
+ //console.log('onload start');
|
|
|
+ playerDispatch({type:'player', player: player});
|
|
|
+ }
|
|
|
+ const playerOnEnd = () => {
|
|
|
+ //console.log('end');
|
|
|
+ }
|
|
|
+ const onSeek = (data) => {
|
|
|
+ //console.log(data)
|
|
|
+ if(data.seekTime===0 && data.currentTime===0) {
|
|
|
+ playerDispatch({type:'paused', setPaused: true});
|
|
|
+ playerDispatch({type:'currentTime', setCurrentTime: 0});
|
|
|
+ }
|
|
|
+ }
|
|
|
return (
|
|
|
- <>
|
|
|
- {/* <C.View
|
|
|
- style={{ ...StyleSheet.absoluteFillObject, zIndex: 1000, marginTop:getStatusBarHeight(true) }}
|
|
|
- cls="h20 bgc-rgba-white-0_5"
|
|
|
- >
|
|
|
- <C.Text cls="f5 ta-c bgc-rgba-red-0_5">테스트용 Component</C.Text>
|
|
|
- <C.View cls="h10 ai-c bgc-rgba-blue-0_5">
|
|
|
- <Slider
|
|
|
- style={{ width: '95%' }}
|
|
|
- trackStyle={{ height: 2 }}
|
|
|
- thumbTintColor="#333"
|
|
|
- thumbStyle={{ width: 10, height: 5 }}
|
|
|
- value={currentPlayerValue}
|
|
|
- onValueChange={value => setCurrentPlayerValue(value)}
|
|
|
- />
|
|
|
- <C.View cls="w95 jc-sb flx-row">
|
|
|
- <C.Text>Time : {currentPlayerValue}</C.Text>
|
|
|
- </C.View>
|
|
|
- </C.View>
|
|
|
- <C.TouchableOpacity
|
|
|
- cls="h5 bgc-rgba-black-0_5"
|
|
|
- onPress={() => {
|
|
|
- setPlay(!isPlay);
|
|
|
- }}
|
|
|
- >
|
|
|
- <C.Text cls="f5 ta-c rgba-white-0_5">Click Test</C.Text>
|
|
|
- </C.TouchableOpacity>
|
|
|
- </C.View> */}
|
|
|
- <PanGestureHandler
|
|
|
- onHandlerStateChange={onGestureEvent}
|
|
|
- activeOffsetY={[-10, 10]}
|
|
|
- onGestureEvent={onGestureEvent}
|
|
|
- >
|
|
|
- <Animated.View
|
|
|
- style={{
|
|
|
- ...StyleSheet.absoluteFillObject,
|
|
|
- zIndex: 10,
|
|
|
- marginTop: statusBarHeight,
|
|
|
- transform: [{ translateY }],
|
|
|
- alignItems: 'center',
|
|
|
- height: mainPlayerContainerHeight
|
|
|
- }}
|
|
|
- >
|
|
|
- <Animated.View
|
|
|
- style={{
|
|
|
- padding: 0,
|
|
|
- backgroundColor: 'white',
|
|
|
- width: playContainerWidth,
|
|
|
- borderRadius: playerBoderRadius
|
|
|
- }}
|
|
|
+ <>
|
|
|
+ {/* <C.View
|
|
|
+ style={{ ...StyleSheet.absoluteFillObject, zIndex: 1000, marginTop:getStatusBarHeight(true) }}
|
|
|
+ cls="h20 bgc-rgba-white-0_5"
|
|
|
>
|
|
|
- <Animated.View
|
|
|
- style={[
|
|
|
- Platform.OS === 'android'
|
|
|
- ? { borderColor: '#eee' }
|
|
|
- : { borderColor: 'white' },
|
|
|
- {
|
|
|
- ...StyleSheet.absoluteFillObject,
|
|
|
- borderWidth: 1,
|
|
|
- borderRadius: 15,
|
|
|
- opacity: playerControlOpaciy,
|
|
|
- backgroundColor: 'white'
|
|
|
- },
|
|
|
- shadow2
|
|
|
- ]}
|
|
|
- >
|
|
|
- <PlayerControls
|
|
|
- {...props}
|
|
|
- currentPlayerValue={currentPlayerValue}
|
|
|
- setCurrentPlayerValue={setCurrentPlayerValue}
|
|
|
+ <C.Text cls="f5 ta-c bgc-rgba-red-0_5">테스트용 Component</C.Text>
|
|
|
+ <C.View cls="h10 ai-c bgc-rgba-blue-0_5">
|
|
|
+ <Slider
|
|
|
+ style={{ width: '95%' }}
|
|
|
+ trackStyle={{ height: 2 }}
|
|
|
+ thumbTintColor="#333"
|
|
|
+ thumbStyle={{ width: 10, height: 5 }}
|
|
|
+ value={currentPlayerValue}
|
|
|
+ onValueChange={value => setCurrentPlayerValue(value)}
|
|
|
/>
|
|
|
- </Animated.View>
|
|
|
+ <C.View cls="w95 jc-sb flx-row">
|
|
|
+ <C.Text>Time : {currentPlayerValue}</C.Text>
|
|
|
+ </C.View>
|
|
|
+ </C.View>
|
|
|
+ <C.TouchableOpacity
|
|
|
+ cls="h5 bgc-rgba-black-0_5"
|
|
|
+ onPress={() => {
|
|
|
+ setPlay(!isPlay);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <C.Text cls="f5 ta-c rgba-white-0_5">Click Test</C.Text>
|
|
|
+ </C.TouchableOpacity>
|
|
|
+ </C.View> */}
|
|
|
+ <PanGestureHandler
|
|
|
+ onHandlerStateChange={onGestureEvent}
|
|
|
+ activeOffsetY={[-10, 10]}
|
|
|
+ onGestureEvent={onGestureEvent}
|
|
|
+ >
|
|
|
<Animated.View
|
|
|
style={{
|
|
|
- opacity: PlayerHeadOpacity,
|
|
|
- backgroundColor: 'rgba(255,255,255,0)',
|
|
|
- width: PlayerHeadWidth,
|
|
|
- height: PlayerHeadHeight
|
|
|
+ ...StyleSheet.absoluteFillObject,
|
|
|
+ zIndex: 10,
|
|
|
+ marginTop: statusBarHeight,
|
|
|
+ transform: [{ translateY }],
|
|
|
+ alignItems: 'center',
|
|
|
+ height: mainPlayerContainerHeight
|
|
|
}}
|
|
|
>
|
|
|
- <PlayerHeader {...props} visibleMenu={setModalVisible} />
|
|
|
- </Animated.View>
|
|
|
- <Animated.View style={{ width: videoWidth, height: videoHeight }}>
|
|
|
- <Animated.Image
|
|
|
- resizeMode="contain"
|
|
|
- style={{ flex: 1, margin: 10, width: null, height: null }}
|
|
|
- source={props.Pages.img}
|
|
|
- />
|
|
|
+ <Animated.View
|
|
|
+ style={{
|
|
|
+ padding: 0,
|
|
|
+ backgroundColor: 'white',
|
|
|
+ width: playContainerWidth,
|
|
|
+ borderRadius: playerBoderRadius
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Animated.View
|
|
|
+ style={[
|
|
|
+ Platform.OS === 'android'
|
|
|
+ ? { borderColor: '#eee' }
|
|
|
+ : { borderColor: 'white' },
|
|
|
+ {
|
|
|
+ ...StyleSheet.absoluteFillObject,
|
|
|
+ borderWidth: 1,
|
|
|
+ borderRadius: 15,
|
|
|
+ opacity: playerControlOpaciy,
|
|
|
+ backgroundColor: 'white'
|
|
|
+ },
|
|
|
+ shadow2
|
|
|
+ ]}
|
|
|
+ >
|
|
|
+ <PlayerControls
|
|
|
+ {...props}
|
|
|
+ />
|
|
|
+ </Animated.View>
|
|
|
+ <Animated.View
|
|
|
+ style={{
|
|
|
+ opacity: PlayerHeadOpacity,
|
|
|
+ backgroundColor: 'rgba(255,255,255,0)',
|
|
|
+ width: PlayerHeadWidth,
|
|
|
+ height: PlayerHeadHeight
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <PlayerHeader {...props} visibleMenu={setModalVisible} />
|
|
|
+ </Animated.View>
|
|
|
+ <Animated.View style={{ width: videoWidth, height: videoHeight }}>
|
|
|
+ <Animated.Image
|
|
|
+ resizeMode="contain"
|
|
|
+ style={{ flex: 1, margin: 10, width: null, height: null }}
|
|
|
+ source={props.Pages.img}
|
|
|
+ />
|
|
|
+ <Video
|
|
|
+ source={{uri:uri}}
|
|
|
+ style={StyleSheet.absoluteFill}
|
|
|
+ ref={player}
|
|
|
+ //rate={this.state.rate}
|
|
|
+ paused={paused}
|
|
|
+ //volume={this.state.volume}
|
|
|
+ muted={muted}
|
|
|
+ //ignoreSilentSwitch={this.state.ignoreSilentSwitch}
|
|
|
+ resizeMode='contain'
|
|
|
+ onLoad={playerOnLoad}
|
|
|
+ onLoadStart={onLoadStart}
|
|
|
+ onBuffer={playerOnBuffer}
|
|
|
+ onProgress={playerOnProgress}
|
|
|
+ onSeek={onSeek}
|
|
|
+ onError={playerOnError}
|
|
|
+ onEnd={playerOnEnd}
|
|
|
+ //poster='https://baconmockup.com/300/200/'
|
|
|
+ //repeat={true}
|
|
|
+ //filter={this.state.filter}
|
|
|
+ //filterEnabled={this.state.filterEnabled}
|
|
|
+ audioOnly={true}
|
|
|
+ />
|
|
|
+ </Animated.View>
|
|
|
+ </Animated.View>
|
|
|
+ <Animated.View
|
|
|
+ style={{
|
|
|
+ backgroundColor: 'white',
|
|
|
+ width: playContainerWidth,
|
|
|
+ height: playerContainerHeight
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Animated.View style={{ opacity }}>
|
|
|
+ <PlayerContents
|
|
|
+ {...props}
|
|
|
+ />
|
|
|
+ </Animated.View>
|
|
|
+ </Animated.View>
|
|
|
</Animated.View>
|
|
|
- </Animated.View>
|
|
|
- <Animated.View
|
|
|
- style={{
|
|
|
- backgroundColor: 'white',
|
|
|
- width: playContainerWidth,
|
|
|
- height: playerContainerHeight
|
|
|
+ </PanGestureHandler>
|
|
|
+ <Modal
|
|
|
+ isVisible={modalVisible === 'detail'}
|
|
|
+ onSwipeComplete={() => {
|
|
|
+ setModalVisible(null);
|
|
|
}}
|
|
|
+ swipeDirection="left"
|
|
|
+ //deviceHeight={height}
|
|
|
+ deviceWidth={width}
|
|
|
+ style={{ margin: 0 }}
|
|
|
+ backdropColor="white"
|
|
|
+ backdropOpacity={1}
|
|
|
+ animationIn="slideInLeft"
|
|
|
+ animationOut="slideOutLeft"
|
|
|
>
|
|
|
- <Animated.View style={{ opacity }}>
|
|
|
- <PlayerContents
|
|
|
- {...props}
|
|
|
- currentPlayerValue={currentPlayerValue}
|
|
|
- setCurrentPlayerValue={setCurrentPlayerValue}
|
|
|
- />
|
|
|
- </Animated.View>
|
|
|
- </Animated.View>
|
|
|
- </Animated.View>
|
|
|
- </PanGestureHandler>
|
|
|
- <Modal
|
|
|
- isVisible={modalVisible === 'detail'}
|
|
|
- onSwipeComplete={() => {
|
|
|
- setModalVisible(null);
|
|
|
- }}
|
|
|
- swipeDirection="left"
|
|
|
- //deviceHeight={height}
|
|
|
- deviceWidth={width}
|
|
|
- style={{ margin: 0 }}
|
|
|
- backdropColor="white"
|
|
|
- backdropOpacity={1}
|
|
|
- animationIn="slideInLeft"
|
|
|
- animationOut="slideOutLeft"
|
|
|
- >
|
|
|
- <C.View cls="w90 h100 bgc-rgba-black-0_5">
|
|
|
- <ScrollView style={{ flex: 1, marginTop: '10%' }}>
|
|
|
- <C.Text cls="flx1 ta-c">{props.Pages.subtitle}</C.Text>
|
|
|
- <C.View cls="flx2 ph5 mt5">
|
|
|
- <C.Text cls="fw-b">{props.Pages.subtitle}</C.Text>
|
|
|
- <C.Text cls="mt2">{props.Pages.contens}</C.Text>
|
|
|
- <C.Text cls="mt3" numberOfLines={1}>
|
|
|
- by {props.Pages.subtitle.replace(/\r\n|\n|\r/gm, ' ')}
|
|
|
- </C.Text>
|
|
|
- <C.Text cls="mt5 as-e" numberOfLines={1}>
|
|
|
- March 19
|
|
|
- </C.Text>
|
|
|
+ <C.View cls="w90 h100 bgc-rgba-black-0_5">
|
|
|
+ <ScrollView style={{ flex: 1, marginTop: '10%' }}>
|
|
|
+ <C.Text cls="flx1 ta-c">{props.Pages.subtitle}</C.Text>
|
|
|
+ <C.View cls="flx2 ph5 mt5">
|
|
|
+ <C.Text cls="fw-b">{props.Pages.subtitle}</C.Text>
|
|
|
+ <C.Text cls="mt2">{props.Pages.contens}</C.Text>
|
|
|
+ <C.Text cls="mt3" numberOfLines={1}>
|
|
|
+ by {props.Pages.subtitle.replace(/\r\n|\n|\r/gm, ' ')}
|
|
|
+ </C.Text>
|
|
|
+ <C.Text cls="mt5 as-e" numberOfLines={1}>
|
|
|
+ March 19
|
|
|
+ </C.Text>
|
|
|
+ </C.View>
|
|
|
+ </ScrollView>
|
|
|
</C.View>
|
|
|
- </ScrollView>
|
|
|
- </C.View>
|
|
|
- <TouchableOpacity
|
|
|
- style={[
|
|
|
- StyleSheet.absoluteFillObject,
|
|
|
- {
|
|
|
- width: '90%',
|
|
|
- justifyContent: 'center',
|
|
|
- paddingRight: '5%',
|
|
|
- alignItems: 'flex-end'
|
|
|
- }
|
|
|
- ]}
|
|
|
- onPress={() => {
|
|
|
- setModalVisible(null);
|
|
|
- }}
|
|
|
- >
|
|
|
- <C.EL.Icon
|
|
|
- color="rgb(10,132,255)"
|
|
|
- {...C.n2cls('size10')}
|
|
|
- type="ionicon"
|
|
|
- name="md-arrow-dropleft"
|
|
|
- />
|
|
|
- </TouchableOpacity>
|
|
|
- </Modal>
|
|
|
-
|
|
|
- <Modal isVisible={modalVisible === 'share'} style={{ margin: 0 }}>
|
|
|
- <View
|
|
|
- style={{
|
|
|
- flex: 1,
|
|
|
- justifyContent: 'center',
|
|
|
- alignItems: 'center',
|
|
|
- backgroundColor: 'rgb(242,242,247)'
|
|
|
- }}
|
|
|
- >
|
|
|
- <ScrollView>
|
|
|
- <View style={{ height: statusBarHeight }} />
|
|
|
- <View style={{ marginHorizontal: '5%', alignItems: 'flex-end' }}>
|
|
|
+ <TouchableOpacity
|
|
|
+ style={[
|
|
|
+ StyleSheet.absoluteFillObject,
|
|
|
+ {
|
|
|
+ width: '90%',
|
|
|
+ justifyContent: 'center',
|
|
|
+ paddingRight: '5%',
|
|
|
+ alignItems: 'flex-end'
|
|
|
+ }
|
|
|
+ ]}
|
|
|
+ onPress={() => {
|
|
|
+ setModalVisible(null);
|
|
|
+ }}
|
|
|
+ >
|
|
|
<C.EL.Icon
|
|
|
- color="black"
|
|
|
+ color="rgb(10,132,255)"
|
|
|
{...C.n2cls('size10')}
|
|
|
type="ionicon"
|
|
|
- name="md-close"
|
|
|
- onPress={() => {
|
|
|
- setModalVisible(null);
|
|
|
- }}
|
|
|
+ name="md-arrow-dropleft"
|
|
|
/>
|
|
|
- </View>
|
|
|
+ </TouchableOpacity>
|
|
|
+ </Modal>
|
|
|
|
|
|
+ <Modal isVisible={modalVisible === 'share'} style={{ margin: 0 }}>
|
|
|
<View
|
|
|
style={{
|
|
|
- //...shadowImage,
|
|
|
- //backgroundColor: 'white',
|
|
|
- marginHorizontal: '5%',
|
|
|
- width: width * 0.8,
|
|
|
- height: (width * 0.8) / 1.78
|
|
|
+ flex: 1,
|
|
|
+ justifyContent: 'center',
|
|
|
+ alignItems: 'center',
|
|
|
+ backgroundColor: 'rgb(242,242,247)'
|
|
|
}}
|
|
|
>
|
|
|
- <Image
|
|
|
- resizeMode="contain"
|
|
|
- style={{
|
|
|
- flex: 1,
|
|
|
- marginVertical: 10,
|
|
|
- width: null,
|
|
|
- height: null
|
|
|
- }}
|
|
|
- source={props.Pages.img}
|
|
|
- />
|
|
|
- </View>
|
|
|
- <C.View cls="flx-row jc-sa ai-t mt2">
|
|
|
- <C.Text cls="fw-b">{'Spring of Music'}</C.Text>
|
|
|
- <C.Text cls="fw-b">{`18min`}</C.Text>
|
|
|
- </C.View>
|
|
|
+ <ScrollView>
|
|
|
+ <View style={{ height: statusBarHeight }} />
|
|
|
+ <View style={{ marginHorizontal: '5%', alignItems: 'flex-end' }}>
|
|
|
+ <C.EL.Icon
|
|
|
+ color="black"
|
|
|
+ {...C.n2cls('size10')}
|
|
|
+ type="ionicon"
|
|
|
+ name="md-close"
|
|
|
+ onPress={() => {
|
|
|
+ setModalVisible(null);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
|
|
|
- <View style={{ height: minHeight }} />
|
|
|
+ <View
|
|
|
+ style={{
|
|
|
+ //...shadowImage,
|
|
|
+ //backgroundColor: 'white',
|
|
|
+ marginHorizontal: '5%',
|
|
|
+ width: width * 0.8,
|
|
|
+ height: (width * 0.8) / 1.78
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ resizeMode="contain"
|
|
|
+ style={{
|
|
|
+ flex: 1,
|
|
|
+ marginVertical: 10,
|
|
|
+ width: null,
|
|
|
+ height: null
|
|
|
+ }}
|
|
|
+ source={props.Pages.img}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ <C.View cls="flx-row jc-sa ai-t mt2">
|
|
|
+ <C.Text cls="fw-b">{'Spring of Music'}</C.Text>
|
|
|
+ <C.Text cls="fw-b">{`18min`}</C.Text>
|
|
|
+ </C.View>
|
|
|
|
|
|
- <TouchableOpacity
|
|
|
- onPress={onShare}
|
|
|
- style={{ marginHorizontal: '5%', alignItems: 'center' }}
|
|
|
- >
|
|
|
- <View style={[s.sharContainer]}>
|
|
|
- <C.EL.Icon
|
|
|
- color="black"
|
|
|
- {...C.n2cls('size10')}
|
|
|
- type="ionicon"
|
|
|
- name="md-share"
|
|
|
- />
|
|
|
- <C.Text cls="f2.5">공유하기, 메세지 보내기</C.Text>
|
|
|
- </View>
|
|
|
- </TouchableOpacity>
|
|
|
+ <View style={{ height: minHeight }} />
|
|
|
+
|
|
|
+ <TouchableOpacity
|
|
|
+ onPress={onShare}
|
|
|
+ style={{ marginHorizontal: '5%', alignItems: 'center' }}
|
|
|
+ >
|
|
|
+ <View style={[s.sharContainer]}>
|
|
|
+ <C.EL.Icon
|
|
|
+ color="black"
|
|
|
+ {...C.n2cls('size10')}
|
|
|
+ type="ionicon"
|
|
|
+ name="md-share"
|
|
|
+ />
|
|
|
+ <C.Text cls="f2.5">공유하기, 메세지 보내기</C.Text>
|
|
|
+ </View>
|
|
|
+ </TouchableOpacity>
|
|
|
|
|
|
- <View style={{ height: minHeight }} />
|
|
|
- </ScrollView>
|
|
|
- </View>
|
|
|
- </Modal>
|
|
|
- </>
|
|
|
+ <View style={{ height: minHeight }} />
|
|
|
+ </ScrollView>
|
|
|
+ </View>
|
|
|
+ </Modal>
|
|
|
+ </>
|
|
|
);
|
|
|
};
|
|
|
|