chore(example/basic): refactor state variable (#3949)

* refactor: basic example from class component to functional component

* refactor: toast component path

* refactor: bufferConfig prop

* refacotr: import component path

* fix: seekbar issue on iOS

* refactor: state variable

* chore: refactor overlay component according to new state structure
This commit is contained in:
Seyed Mostafa Hasani
2024-07-08 11:24:32 +03:30
committed by GitHub
parent 7562669fd6
commit a3ecc0108c
4 changed files with 305 additions and 266 deletions

View File

@@ -13,13 +13,17 @@ import MultiValueControl, {
MultiValueControlPropType,
} from '../MultiValueControl.tsx';
import {
AudioTrack,
ResizeMode,
SelectedTrack,
SelectedTrackType,
SelectedVideoTrack,
SelectedVideoTrackType,
TextTrack,
VideoDecoderProperties,
VideoRef,
VideoTrack,
} from 'react-native-video';
import {StateType} from '../types';
import {
toast,
Seeker,
@@ -32,12 +36,91 @@ import {
type Props = {
channelDown: () => void;
channelUp: () => void;
setState: (value: StateType) => void;
state: StateType;
fullscreen: boolean;
setFullscreen: (value: boolean) => void;
controls: boolean;
setControls: (value: boolean) => void;
decoration: boolean;
setDecoration: (value: boolean) => void;
showNotificationControls: boolean;
setShowNotificationControls: (value: boolean) => void;
selectedAudioTrack: SelectedTrack | undefined;
setSelectedAudioTrack: (value: SelectedTrack | undefined) => void;
selectedTextTrack: SelectedTrack | undefined;
setSelectedTextTrack: (value: SelectedTrack | undefined) => void;
selectedVideoTrack: SelectedVideoTrack;
setSelectedVideoTrack: (value: SelectedVideoTrack) => void;
setIsSeeking: (value: boolean) => void;
rate: number;
setRate: (value: number) => void;
volume: number;
setVolume: (value: number) => void;
resizeMode: ResizeMode;
setResizeMode: (value: ResizeMode) => void;
isLoading: boolean;
srcListId: number;
useCache: boolean;
setUseCache: (value: boolean) => void;
paused: boolean;
setPaused: (value: boolean) => void;
repeat: boolean;
setRepeat: (value: boolean) => void;
poster: string | undefined;
setPoster: (value: string | undefined) => void;
muted: boolean;
setMuted: (value: boolean) => void;
currentTime: number;
duration: number;
isSeeking: boolean;
audioTracks: AudioTrack[];
textTracks: TextTrack[];
videoTracks: VideoTrack[];
};
const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
const {state, setState, channelUp, channelDown} = props;
const {
channelUp,
channelDown,
setFullscreen,
fullscreen,
setControls,
controls,
setDecoration,
decoration,
setShowNotificationControls,
showNotificationControls,
setSelectedAudioTrack,
setSelectedTextTrack,
setSelectedVideoTrack,
setIsSeeking,
rate,
setRate,
volume,
setVolume,
resizeMode,
setResizeMode,
isLoading,
srcListId,
setUseCache,
useCache,
paused,
setPaused,
setRepeat,
repeat,
setPoster,
poster,
setMuted,
muted,
duration,
isSeeking,
currentTime,
textTracks,
videoTracks,
audioTracks,
selectedAudioTrack,
selectedVideoTrack,
selectedTextTrack,
} = props;
const popupInfo = useCallback(() => {
VideoDecoderProperties.getWidevineLevel().then((widevineLevel: number) => {
VideoDecoderProperties.isHEVCSupported().then((hevc: string) => {
@@ -59,82 +142,62 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
}, []);
const toggleFullscreen = () => {
setState({...state, fullscreen: !state.fullscreen});
setFullscreen(!fullscreen);
};
const toggleControls = () => {
setState({...state, showRNVControls: !state.showRNVControls});
setControls(!controls);
};
const toggleDecoration = () => {
setState({...state, decoration: !state.decoration});
setDecoration(!decoration);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
ref.current?.setFullScreen(!state.decoration);
ref.current?.setFullScreen(!decoration);
};
const toggleShowNotificationControls = () => {
setState({
...state,
showNotificationControls: !state.showNotificationControls,
});
setShowNotificationControls(!showNotificationControls);
};
const onSelectedAudioTrackChange = (itemValue: string) => {
console.log('on audio value change ' + itemValue);
if (itemValue === 'none') {
setState({
...state,
selectedAudioTrack: {
type: SelectedTrackType.DISABLED,
},
setSelectedAudioTrack({
type: SelectedTrackType.DISABLED,
});
} else {
setState({
...state,
selectedAudioTrack: {
type: SelectedTrackType.INDEX,
value: itemValue,
},
setSelectedAudioTrack({
type: SelectedTrackType.INDEX,
value: itemValue,
});
}
};
const onSelectedTextTrackChange = (itemValue: string) => {
console.log('on value change ' + itemValue);
setState({
...state,
selectedTextTrack: {
type:
textTracksSelectionBy === 'index'
? SelectedTrackType.INDEX
: SelectedTrackType.LANGUAGE,
value: itemValue,
},
});
const type =
textTracksSelectionBy === 'index'
? SelectedTrackType.INDEX
: SelectedTrackType.LANGUAGE;
setSelectedTextTrack({type, value: itemValue});
};
const onSelectedVideoTrackChange = (itemValue: string) => {
console.log('on value change ' + itemValue);
if (itemValue === undefined || itemValue === 'auto') {
setState({
...state,
selectedVideoTrack: {
type: SelectedVideoTrackType.AUTO,
},
setSelectedVideoTrack({
type: SelectedVideoTrackType.AUTO,
});
} else {
setState({
...state,
selectedVideoTrack: {
type: SelectedVideoTrackType.INDEX,
value: itemValue,
},
setSelectedVideoTrack({
type: SelectedVideoTrackType.INDEX,
value: itemValue,
});
}
};
const videoSeek = (position: number) => {
setState({...state, isSeeking: true});
setIsSeeking(true);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
ref.current?.seek(position);
@@ -142,33 +205,45 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
const onRateSelected = (value: MultiValueControlPropType) => {
if (typeof value === 'number') {
setState({...state, rate: value});
}
};
const onVolumeSelected = (value: MultiValueControlPropType) => {
if (typeof value === 'number') {
setState({...state, volume: value});
}
};
const onResizeModeSelected = (value: MultiValueControlPropType) => {
if (typeof value === 'object') {
setState({...state, resizeMode: value});
setRate(value);
}
};
const onVolumeSelected = (value: MultiValueControlPropType) => {
if (typeof value === 'number') {
setVolume(value);
}
};
const onResizeModeSelected = (value: MultiValueControlPropType) => {
if (typeof value === 'object') {
setResizeMode(value);
}
};
const toggleCache = () => setUseCache(!useCache);
const togglePause = () => setPaused(!paused);
const toggleRepeat = () => setRepeat(!repeat);
const togglePoster = () => setPoster(poster ? undefined : samplePoster);
const toggleMuted = () => setMuted(!muted);
return (
<>
<Indicator isLoading={state.isLoading} />
<Indicator isLoading={isLoading} />
<View style={styles.topControls}>
<View style={styles.resizeModeControl}>
<TopControl
srcListId={state.srcListId}
showRNVControls={state.showRNVControls}
srcListId={srcListId}
showRNVControls={controls}
toggleControls={toggleControls}
/>
</View>
</View>
{!state.showRNVControls ? (
{!controls ? (
<>
<View style={styles.leftControls}>
<ToggleControl onPress={channelDown} text="ChDown" />
@@ -182,46 +257,35 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
<View style={styles.generalControls}>
<ToggleControl onPress={popupInfo} text="decoderInfo" />
<ToggleControl
isSelected={state.useCache}
onPress={() => {
setState({...state, useCache: !state.useCache});
}}
isSelected={useCache}
onPress={toggleCache}
selectedText="enable cache"
unselectedText="disable cache"
/>
</View>
) : null}
<ToggleControl
isSelected={state.paused}
onPress={() => {
setState({...state, paused: !state.paused});
}}
isSelected={paused}
onPress={togglePause}
selectedText="pause"
unselectedText="playing"
/>
<ToggleControl
isSelected={state.loop}
onPress={() => {
setState({...state, loop: !state.loop});
}}
isSelected={repeat}
onPress={toggleRepeat}
selectedText="loop enable"
unselectedText="loop disable"
/>
<ToggleControl onPress={toggleFullscreen} text="fullscreen" />
<ToggleControl onPress={toggleDecoration} text="decoration" />
<ToggleControl
isSelected={!!state.poster}
onPress={() => {
setState({
...state,
poster: state.poster ? undefined : samplePoster,
});
}}
isSelected={!!poster}
onPress={togglePoster}
selectedText="poster"
unselectedText="no poster"
/>
<ToggleControl
isSelected={state.showNotificationControls}
isSelected={showNotificationControls}
onPress={toggleShowNotificationControls}
selectedText="hide notification controls"
unselectedText="show notification controls"
@@ -232,13 +296,13 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
<MultiValueControl
values={[0, 0.25, 0.5, 1.0, 1.5, 2.0]}
onPress={onRateSelected}
selected={state.rate}
selected={rate}
/>
{/* shall be replaced by slider */}
<MultiValueControl
values={[0.5, 1, 1.5]}
onPress={onVolumeSelected}
selected={state.volume}
selected={volume}
/>
<MultiValueControl
values={[
@@ -247,18 +311,16 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
ResizeMode.STRETCH,
]}
onPress={onResizeModeSelected}
selected={state.resizeMode}
selected={resizeMode}
/>
<ToggleControl
isSelected={state.muted}
onPress={() => {
setState({...state, muted: !state.muted});
}}
isSelected={muted}
onPress={toggleMuted}
text="muted"
/>
{isIos ? (
<ToggleControl
isSelected={state.paused}
isSelected={paused}
onPress={() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
@@ -276,27 +338,27 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
) : null}
</View>
<Seeker
currentTime={state.currentTime}
duration={state.duration}
isLoading={state.isLoading}
currentTime={currentTime}
duration={duration}
isLoading={isLoading}
videoSeek={prop => videoSeek(prop)}
isUISeeking={state.isSeeking}
isUISeeking={isSeeking}
/>
<View style={styles.generalControls}>
<AudioTrackSelector
audioTracks={state.audioTracks}
selectedAudioTrack={state.selectedAudioTrack}
audioTracks={audioTracks}
selectedAudioTrack={selectedAudioTrack}
onValueChange={onSelectedAudioTrackChange}
/>
<TextTrackSelector
textTracks={state.textTracks}
selectedTextTrack={state.selectedTextTrack}
textTracks={textTracks}
selectedTextTrack={selectedTextTrack}
onValueChange={onSelectedTextTrackChange}
textTracksSelectionBy={textTracksSelectionBy}
/>
<VideoTrackSelector
videoTracks={state.videoTracks}
selectedVideoTrack={state.selectedVideoTrack}
videoTracks={videoTracks}
selectedVideoTrack={selectedVideoTrack}
onValueChange={onSelectedVideoTrackChange}
/>
</View>