feat: add ability to define poster props as Image type and render poster as custom component (#3972)

This commit is contained in:
Kamil Moskała
2024-07-22 22:38:35 +02:00
committed by GitHub
parent 1ee5811c8e
commit adbd06e2df
10 changed files with 184 additions and 72 deletions

View File

@@ -34,7 +34,7 @@ import Video, {
import styles from './styles';
import {type AdditionalSourceInfo} from './types';
import {bufferConfig, srcList, textTracksSelectionBy} from './constants';
import {Overlay, toast} from './components';
import {Overlay, toast, VideoLoader} from './components';
type Props = NonNullable<unknown>;
@@ -68,7 +68,7 @@ const VideoPlayer: FC<Props> = ({}) => {
const [repeat, setRepeat] = useState(false);
const [controls, setControls] = useState(false);
const [useCache, setUseCache] = useState(false);
const [poster, setPoster] = useState<string | undefined>(undefined);
const [showPoster, setShowPoster] = useState<boolean>(false);
const [showNotificationControls, setShowNotificationControls] =
useState(false);
const [isSeeking, setIsSeeking] = useState(false);
@@ -234,7 +234,6 @@ const VideoPlayer: FC<Props> = ({}) => {
paused={paused}
volume={volume}
muted={muted}
fullscreen={fullscreen}
controls={controls}
resizeMode={resizeMode}
onFullscreenPlayerWillDismiss={onFullScreenExit}
@@ -264,7 +263,7 @@ const VideoPlayer: FC<Props> = ({}) => {
cacheSizeMB: useCache ? 200 : 0,
}}
preventsDisplaySleepDuringVideoPlayback={true}
poster={poster}
renderLoader={showPoster ? <VideoLoader /> : undefined}
onPlaybackRateChange={onPlaybackRateChange}
onPlaybackStateChanged={onPlaybackStateChanged}
bufferingStrategy={BufferingStrategyType.DEFAULT}
@@ -294,7 +293,7 @@ const VideoPlayer: FC<Props> = ({}) => {
paused={paused}
volume={volume}
setControls={setControls}
poster={poster}
showPoster={showPoster}
rate={rate}
setFullscreen={setFullscreen}
setPaused={setPaused}
@@ -303,7 +302,7 @@ const VideoPlayer: FC<Props> = ({}) => {
setIsSeeking={setIsSeeking}
repeat={repeat}
setRepeat={setRepeat}
setPoster={setPoster}
setShowPoster={setShowPoster}
setRate={setRate}
setResizeMode={setResizeMode}
setShowNotificationControls={setShowNotificationControls}

View File

@@ -1,22 +1,8 @@
import React, {FC, memo} from 'react';
import {ActivityIndicator, View} from 'react-native';
import styles from '../styles.tsx';
import React, {memo} from 'react';
import {ActivityIndicator} from 'react-native';
type Props = {
isLoading: boolean;
};
const _Indicator: FC<Props> = ({isLoading}) => {
if (!isLoading) {
return <View />;
}
return (
<ActivityIndicator
color="#3235fd"
size="large"
style={styles.IndicatorStyle}
/>
);
const _Indicator = () => {
return <ActivityIndicator color="#3235fd" size="large" />;
};
export const Indicator = memo(_Indicator);

View File

@@ -5,19 +5,11 @@ import React, {
type Dispatch,
type SetStateAction,
} from 'react';
import {Indicator} from './Indicator.tsx';
import {View} from 'react-native';
import styles from '../styles.tsx';
import ToggleControl from '../ToggleControl.tsx';
import {
isAndroid,
isIos,
samplePoster,
textTracksSelectionBy,
} from '../constants';
import MultiValueControl, {
type MultiValueControlPropType,
} from '../MultiValueControl.tsx';
import {isAndroid, isIos, textTracksSelectionBy} from '../constants';
import MultiValueControl from '../MultiValueControl.tsx';
import {
ResizeMode,
VideoRef,
@@ -69,8 +61,8 @@ type Props = {
setPaused: Dispatch<SetStateAction<boolean>>;
repeat: boolean;
setRepeat: Dispatch<SetStateAction<boolean>>;
poster: string | undefined;
setPoster: Dispatch<SetStateAction<string | undefined>>;
showPoster: boolean;
setShowPoster: Dispatch<SetStateAction<boolean>>;
muted: boolean;
setMuted: Dispatch<SetStateAction<boolean>>;
currentTime: number;
@@ -108,8 +100,8 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
setPaused,
setRepeat,
repeat,
setPoster,
poster,
setShowPoster,
showPoster,
setMuted,
muted,
duration,
@@ -217,14 +209,12 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
const toggleRepeat = () => setRepeat(prev => !prev);
const togglePoster = () =>
setPoster(prev => (prev ? undefined : samplePoster));
const togglePoster = () => setShowPoster(prev => !prev);
const toggleMuted = () => setMuted(prev => !prev);
return (
<>
<Indicator isLoading={isLoading} />
<View style={styles.topControls}>
<View style={styles.resizeModeControl}>
<TopControl
@@ -270,7 +260,7 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
<ToggleControl onPress={toggleFullscreen} text="fullscreen" />
<ToggleControl onPress={openDecoration} text="decoration" />
<ToggleControl
isSelected={!!poster}
isSelected={showPoster}
onPress={togglePoster}
selectedText="poster"
unselectedText="no poster"

View File

@@ -0,0 +1,15 @@
import {Text, View} from 'react-native';
import {Indicator} from './Indicator.tsx';
import React, {memo} from 'react';
import styles from '../styles.tsx';
const _VideoLoader = () => {
return (
<View style={styles.indicatorContainer}>
<Text style={styles.indicatorText}>Loading...</Text>
<Indicator />
</View>
);
};
export const VideoLoader = memo(_VideoLoader);

View File

@@ -1,3 +1,4 @@
export * from './VideoLoader';
export * from './Indicator';
export * from './Seeker';
export * from './AudioTracksSelector';

View File

@@ -149,10 +149,6 @@ export const srcAndroidList = [
},
];
// poster which can be displayed
export const samplePoster =
'https://upload.wikimedia.org/wikipedia/commons/1/18/React_Native_Logo.png';
export const srcList: SampleVideoSource[] = srcAllPlatformList.concat(
isAndroid ? srcAndroidList : srcIosList,
);

View File

@@ -102,9 +102,15 @@ const styles = StyleSheet.create({
borderWidth: 1,
borderColor: 'red',
},
IndicatorStyle: {
flex: 1,
indicatorContainer: {
justifyContent: 'center',
alignItems: 'center',
gap: 10,
width: '100%',
height: '100%',
},
indicatorText: {
color: 'white',
},
seekbarContainer: {
flex: 1,