mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-22 12:51:42 +03:00
unified video player component
This commit is contained in:
parent
e8d0f67619
commit
3a99cb1034
@ -13,7 +13,7 @@ import { navigate } from '../../../../navigation/service';
|
||||
// Constants
|
||||
import { default as ROUTES } from '../../../../constants/routeNames';
|
||||
|
||||
import { PostHtmlRenderer, TextButton } from '../../..';
|
||||
import { PostHtmlRenderer, TextButton, VideoPlayer } from '../../..';
|
||||
|
||||
// Styles
|
||||
import styles from './commentBodyStyles';
|
||||
@ -21,14 +21,12 @@ import styles from './commentBodyStyles';
|
||||
// Services and Actions
|
||||
import { writeToClipboard } from '../../../../utils/clipboard';
|
||||
import { toastNotification } from '../../../../redux/actions/uiAction';
|
||||
import VideoPlayerSheet from './videoPlayerSheet';
|
||||
import { LongPressGestureHandler, State } from 'react-native-gesture-handler';
|
||||
import { useCallback } from 'react';
|
||||
import { OptionsModal } from '../../../atoms';
|
||||
import { useAppDispatch } from '../../../../hooks';
|
||||
import { isCommunity } from '../../../../utils/communityValidation';
|
||||
import { GLOBAL_POST_FILTERS_VALUE } from '../../../../constants/options/filters';
|
||||
import { startsWith } from 'core-js/core/string';
|
||||
|
||||
const WIDTH = Dimensions.get('window').width;
|
||||
|
||||
@ -368,7 +366,12 @@ const CommentBody = ({
|
||||
setVideoUrl(null);
|
||||
}}
|
||||
>
|
||||
<VideoPlayerSheet youtubeVideoId={youtubeVideoId} videoUrl={videoUrl} startTime={videoStartTime} />
|
||||
<VideoPlayer
|
||||
mode={youtubeVideoId ? 'youtube' : 'url'}
|
||||
youtubeVideoId={youtubeVideoId}
|
||||
videoUrl={videoUrl}
|
||||
startTime={videoStartTime}
|
||||
/>
|
||||
</ActionsSheetView>
|
||||
</Fragment>
|
||||
);
|
||||
|
@ -15,11 +15,10 @@ import { toastNotification } from '../../../../redux/actions/uiAction';
|
||||
|
||||
// Constants
|
||||
import { default as ROUTES } from '../../../../constants/routeNames';
|
||||
import VideoPlayerSheet from './videoPlayerSheet';
|
||||
import { OptionsModal } from '../../../atoms';
|
||||
import { isCommunity } from '../../../../utils/communityValidation';
|
||||
import { GLOBAL_POST_FILTERS_VALUE } from '../../../../constants/options/filters';
|
||||
import { PostHtmlRenderer } from '../../..';
|
||||
import { PostHtmlRenderer, VideoPlayer } from '../../..';
|
||||
|
||||
const WIDTH = Dimensions.get('window').width;
|
||||
|
||||
@ -294,7 +293,8 @@ const PostBody = ({ navigation, body, dispatch, onLoadEnd }) => {
|
||||
setVideoUrl(null);
|
||||
}}
|
||||
>
|
||||
<VideoPlayerSheet
|
||||
<VideoPlayer
|
||||
mode={youtubeVideoId ? 'youtube' : 'url'}
|
||||
youtubeVideoId={youtubeVideoId}
|
||||
videoUrl={videoUrl}
|
||||
startTime={videoStartTime}
|
||||
|
@ -1,83 +0,0 @@
|
||||
import React, {useState} from 'react';
|
||||
import { Dimensions } from 'react-native';
|
||||
import { View, StyleSheet, ActivityIndicator } from 'react-native';
|
||||
import WebView from 'react-native-webview';
|
||||
import YoutubeIframe, { InitialPlayerParams } from 'react-native-youtube-iframe';
|
||||
|
||||
interface VideoPlayerSheetProps {
|
||||
youtubeVideoId?:string;
|
||||
videoUrl?:string;
|
||||
startTime?:number;
|
||||
}
|
||||
|
||||
const VideoPlayerSheet = ({youtubeVideoId, videoUrl, startTime}: VideoPlayerSheetProps) => {
|
||||
|
||||
const PLAYER_HEIGHT = Dimensions.get('screen').width * (9/16);
|
||||
|
||||
const [shouldPlay, setShouldPlay] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const _onReady = () => {
|
||||
setLoading(false)
|
||||
setShouldPlay(true);
|
||||
}
|
||||
|
||||
const _onChangeState = (event:string) => {
|
||||
setShouldPlay(!(event == 'paused' || event == 'ended'));
|
||||
}
|
||||
|
||||
const _onError = () => {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
const initialParams:InitialPlayerParams = {
|
||||
start:startTime
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
|
||||
{youtubeVideoId &&
|
||||
<YoutubeIframe
|
||||
height={PLAYER_HEIGHT}
|
||||
videoId={youtubeVideoId}
|
||||
initialPlayerParams={initialParams}
|
||||
onReady={_onReady}
|
||||
play={shouldPlay}
|
||||
onChangeState={_onChangeState}
|
||||
onError={_onError}
|
||||
/>
|
||||
|
||||
}{
|
||||
videoUrl &&
|
||||
<View style={{height:PLAYER_HEIGHT}}>
|
||||
<WebView
|
||||
scalesPageToFit={true}
|
||||
bounces={false}
|
||||
javaScriptEnabled={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
onLoadEnd={()=>{
|
||||
setLoading(false);
|
||||
}}
|
||||
onLoadStart={()=>{
|
||||
setLoading(true);
|
||||
}}
|
||||
source={{uri:videoUrl}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
}
|
||||
{loading && <ActivityIndicator style={styles.activityIndicator}/>}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoPlayerSheet;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingVertical:16,
|
||||
},
|
||||
activityIndicator: {
|
||||
position:'absolute', alignItems:'center', justifyContent:'center', top:0, bottom:0, left:0, right:0}
|
||||
});
|
@ -218,43 +218,31 @@ export const PostHtmlRenderer = memo(
|
||||
return <TDefaultRenderer {...props} />;
|
||||
};
|
||||
|
||||
|
||||
// iframe renderer for rendering iframes in body
|
||||
const _iframeRenderer = function IframeRenderer(props) {
|
||||
const iframeProps = useHtmlIframeProps(props);
|
||||
const checkSrcRegex = /(.*?)\.(mp4|webm|ogg)$/gi;
|
||||
const isVideoType = iframeProps.source.uri.match(checkSrcRegex);
|
||||
const isVideoFormat = iframeProps.source.uri.match(checkSrcRegex);
|
||||
|
||||
const src = isVideoType
|
||||
? {
|
||||
html: `
|
||||
<video width="100%" height="auto" controls>
|
||||
<source src="${iframeProps.source.uri}" type="video/mp4">
|
||||
</video>
|
||||
`,
|
||||
}
|
||||
: {
|
||||
uri: iframeProps.source.uri,
|
||||
};
|
||||
return (
|
||||
<WebView
|
||||
scalesPageToFit={true}
|
||||
bounces={false}
|
||||
javaScriptEnabled={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
onLoadEnd={() => {
|
||||
console.log('load end');
|
||||
}}
|
||||
onLoadStart={() => {
|
||||
console.log('load start');
|
||||
}}
|
||||
source={src}
|
||||
style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
|
||||
startInLoadingState={true}
|
||||
onShouldStartLoadWithRequest={() => true}
|
||||
mediaPlaybackRequiresUserAction={true}
|
||||
allowsInlineMediaPlayback={true}
|
||||
/>
|
||||
);
|
||||
//this hack help avoid autoplaying fullscreened iframe videos;
|
||||
const src = isVideoFormat ?
|
||||
{
|
||||
html: `
|
||||
<video width="100%" height="auto" controls>
|
||||
<source src="${iframeProps.source.uri}" type="video/mp4">
|
||||
</video>`,
|
||||
}:{
|
||||
uri: iframeProps.source.uri,
|
||||
};
|
||||
|
||||
return (
|
||||
<VideoPlayer
|
||||
mode='source'
|
||||
source={src}
|
||||
contentWidth={contentWidth}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -1,19 +1,29 @@
|
||||
import React, { useState } from 'react';
|
||||
import style from './videoPlayerStyles';
|
||||
import { Dimensions } from 'react-native';
|
||||
import { View, StyleSheet, ActivityIndicator } from 'react-native';
|
||||
import WebView from 'react-native-webview';
|
||||
import YoutubeIframe, { InitialPlayerParams } from 'react-native-youtube-iframe';
|
||||
import { WebViewSource } from 'react-native-webview/lib/WebViewTypes';
|
||||
|
||||
interface VideoPlayerProps {
|
||||
mode: 'source'|'youtube'|'url';
|
||||
contentWidth?: number;
|
||||
youtubeVideoId?: string;
|
||||
videoUrl?: string;
|
||||
startTime?: number;
|
||||
contentWidth?: number;
|
||||
source?: WebViewSource;
|
||||
}
|
||||
|
||||
const VideoPlayer = ({ youtubeVideoId, videoUrl, startTime, contentWidth }: VideoPlayerProps) => {
|
||||
const PLAYER_HEIGHT = Dimensions.get('screen').width * (9 / 16);
|
||||
const VideoPlayer = ({
|
||||
youtubeVideoId,
|
||||
videoUrl,
|
||||
startTime,
|
||||
source,
|
||||
contentWidth = Dimensions.get('screen').width,
|
||||
mode
|
||||
}: VideoPlayerProps) => {
|
||||
|
||||
const PLAYER_HEIGHT = contentWidth * (9 / 16);
|
||||
|
||||
const [shouldPlay, setShouldPlay] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@ -40,7 +50,7 @@ const VideoPlayer = ({ youtubeVideoId, videoUrl, startTime, contentWidth }: Vide
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{youtubeVideoId && (
|
||||
{mode === 'youtube' && youtubeVideoId && (
|
||||
<View style={{ width: contentWidth, height: PLAYER_HEIGHT }}>
|
||||
<YoutubeIframe
|
||||
height={PLAYER_HEIGHT}
|
||||
@ -53,7 +63,7 @@ const VideoPlayer = ({ youtubeVideoId, videoUrl, startTime, contentWidth }: Vide
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
{videoUrl && (
|
||||
{((mode === 'source' && source) || (mode === 'url' && videoUrl)) && (
|
||||
<View style={{ height: PLAYER_HEIGHT }}>
|
||||
<WebView
|
||||
scalesPageToFit={true}
|
||||
@ -66,8 +76,8 @@ const VideoPlayer = ({ youtubeVideoId, videoUrl, startTime, contentWidth }: Vide
|
||||
onLoadStart={() => {
|
||||
setLoading(true);
|
||||
}}
|
||||
source={{ uri: videoUrl }}
|
||||
style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
|
||||
source={source || { uri: videoUrl }}
|
||||
style={{ width: contentWidth, height: PLAYER_HEIGHT}}
|
||||
startInLoadingState={true}
|
||||
onShouldStartLoadWithRequest={() => true}
|
||||
mediaPlaybackRequiresUserAction={true}
|
||||
|
Loading…
Reference in New Issue
Block a user