chore(sample): refactor sample code to follow rn best practices (#3990)

Co-authored-by: Olivier Bouillet <62574056+freeboub@users.noreply.github.com>
This commit is contained in:
Kamil Moskała 2024-07-15 23:29:23 +02:00 committed by GitHub
parent 8ef2df1bac
commit 7611da155f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 111 additions and 112 deletions

View File

@ -1,39 +1,39 @@
'use strict';
import React, {FC, useCallback, useRef, useState} from 'react';
import React, {type FC, useCallback, useRef, useState} from 'react';
import {TouchableOpacity, View} from 'react-native';
import {Platform, TouchableOpacity, View} from 'react-native';
import Video, {
AudioTrack,
OnAudioTracksData,
OnLoadData,
OnProgressData,
OnTextTracksData,
OnVideoAspectRatioData,
TextTrack,
OnBufferData,
OnAudioFocusChangedData,
OnVideoErrorData,
VideoRef,
OnTextTrackDataChangedData,
OnSeekData,
OnPlaybackStateChangedData,
OnPlaybackRateChangeData,
OnVideoTracksData,
SelectedVideoTrackType,
BufferingStrategyType,
ReactVideoSource,
SelectedTrackType,
TextTracks,
ResizeMode,
VideoTrack,
SelectedTrack,
SelectedVideoTrack,
EnumValues,
type AudioTrack,
type OnAudioTracksData,
type OnLoadData,
type OnProgressData,
type OnTextTracksData,
type OnVideoAspectRatioData,
type TextTrack,
type OnBufferData,
type OnAudioFocusChangedData,
type OnVideoErrorData,
type OnTextTrackDataChangedData,
type OnSeekData,
type OnPlaybackStateChangedData,
type OnPlaybackRateChangeData,
type OnVideoTracksData,
type ReactVideoSource,
type TextTracks,
type VideoTrack,
type SelectedTrack,
type SelectedVideoTrack,
type EnumValues,
} from 'react-native-video';
import styles from './styles';
import {AdditionalSourceInfo} from './types';
import {type AdditionalSourceInfo} from './types';
import {bufferConfig, srcList, textTracksSelectionBy} from './constants';
import {Overlay, toast} from './components';
@ -58,7 +58,6 @@ const VideoPlayer: FC<Props> = ({}) => {
const [_, setVideoSize] = useState({videoWidth: 0, videoHeight: 0});
const [paused, setPaused] = useState(false);
const [fullscreen, setFullscreen] = useState(true);
const [decoration, setDecoration] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [audioTracks, setAudioTracks] = useState<AudioTrack[]>([]);
const [textTracks, setTextTracks] = useState<TextTrack[]>([]);
@ -87,6 +86,31 @@ const VideoPlayer: FC<Props> = ({}) => {
const currentSrc = srcList[srcListId];
const additional = currentSrc as AdditionalSourceInfo;
const goToChannel = useCallback((channel: number) => {
setSrcListId(channel);
setDuration(0);
setCurrentTime(0);
setVideoSize({videoWidth: 0, videoHeight: 0});
setIsLoading(false);
setAudioTracks([]);
setTextTracks([]);
setSelectedAudioTrack(undefined);
setSelectedTextTrack(undefined);
setSelectedVideoTrack({
type: SelectedVideoTrackType.AUTO,
});
}, []);
const channelUp = useCallback(() => {
console.log('channel up');
goToChannel((srcListId + 1) % srcList.length);
}, [goToChannel, srcListId]);
const channelDown = useCallback(() => {
console.log('channel down');
goToChannel((srcListId + srcList.length - 1) % srcList.length);
}, [goToChannel, srcListId]);
const onAudioTracks = (data: OnAudioTracksData) => {
const selectedTrack = data.audioTracks?.find((x: AudioTrack) => {
return x.selected;
@ -197,31 +221,11 @@ const VideoPlayer: FC<Props> = ({}) => {
console.log('onPlaybackStateChanged', data);
};
const goToChannel = (channel: number) => {
setSrcListId(channel);
setDuration(0);
setCurrentTime(0);
setVideoSize({videoWidth: 0, videoHeight: 0});
setIsLoading(false);
setAudioTracks([]);
setTextTracks([]);
setSelectedAudioTrack(undefined);
setSelectedTextTrack(undefined);
setSelectedVideoTrack({
type: SelectedVideoTrackType.AUTO,
});
const onFullScreenExit = () => {
// iOS pauses video on exit from full screen
Platform.OS === 'ios' && setPaused(true);
};
const channelUp = useCallback(() => {
console.log('channel up');
goToChannel((srcListId + 1) % srcList.length);
}, [srcListId]);
const channelDown = useCallback(() => {
console.log('channel down');
goToChannel((srcListId + srcList.length - 1) % srcList.length);
}, [srcListId]);
return (
<View style={styles.container}>
{(srcList[srcListId] as AdditionalSourceInfo)?.noView ? null : (
@ -241,6 +245,7 @@ const VideoPlayer: FC<Props> = ({}) => {
fullscreen={fullscreen}
controls={controls}
resizeMode={resizeMode}
onFullscreenPlayerWillDismiss={onFullScreenExit}
onLoad={onLoad}
onAudioTracks={onAudioTracks}
onTextTracks={onTextTracks}
@ -293,14 +298,11 @@ const VideoPlayer: FC<Props> = ({}) => {
currentTime={currentTime}
setMuted={setMuted}
muted={muted}
fullscreen={fullscreen}
duration={duration}
decoration={decoration}
paused={paused}
volume={volume}
setControls={setControls}
poster={poster}
setDecoration={setDecoration}
rate={rate}
setFullscreen={setFullscreen}
setPaused={setPaused}

View File

@ -1,6 +1,6 @@
import {Picker} from '@react-native-picker/picker';
import {Text} from 'react-native';
import {AudioTrack, SelectedTrack} from 'react-native-video';
import type {AudioTrack, SelectedTrack} from 'react-native-video';
import styles from '../styles';
import React from 'react';

View File

@ -1,4 +1,10 @@
import React, {forwardRef, memo, useCallback} from 'react';
import React, {
forwardRef,
memo,
useCallback,
type Dispatch,
type SetStateAction,
} from 'react';
import {Indicator} from './Indicator.tsx';
import {View} from 'react-native';
import styles from '../styles.tsx';
@ -9,19 +15,21 @@ import {
samplePoster,
textTracksSelectionBy,
} from '../constants';
import MultiValueControl from '../MultiValueControl.tsx';
import MultiValueControl, {
type MultiValueControlPropType,
} from '../MultiValueControl.tsx';
import {
AudioTrack,
EnumValues,
ResizeMode,
SelectedTrack,
SelectedTrackType,
SelectedVideoTrack,
SelectedVideoTrackType,
TextTrack,
VideoDecoderProperties,
VideoRef,
VideoTrack,
SelectedTrackType,
SelectedVideoTrackType,
VideoDecoderProperties,
type EnumValues,
type TextTrack,
type SelectedVideoTrack,
type SelectedTrack,
type VideoTrack,
type AudioTrack,
} from 'react-native-video';
import {
toast,
@ -35,39 +43,36 @@ import {
type Props = {
channelDown: () => void;
channelUp: () => void;
fullscreen: boolean;
setFullscreen: (value: boolean) => void;
setFullscreen: Dispatch<SetStateAction<boolean>>;
controls: boolean;
setControls: (value: boolean) => void;
decoration: boolean;
setDecoration: (value: boolean) => void;
setControls: Dispatch<SetStateAction<boolean>>;
showNotificationControls: boolean;
setShowNotificationControls: (value: boolean) => void;
setShowNotificationControls: Dispatch<SetStateAction<boolean>>;
selectedAudioTrack: SelectedTrack | undefined;
setSelectedAudioTrack: (value: SelectedTrack | undefined) => void;
setSelectedAudioTrack: Dispatch<SetStateAction<SelectedTrack | undefined>>;
selectedTextTrack: SelectedTrack | undefined;
setSelectedTextTrack: (value: SelectedTrack | undefined) => void;
selectedVideoTrack: SelectedVideoTrack;
setSelectedVideoTrack: (value: SelectedVideoTrack) => void;
setIsSeeking: (value: boolean) => void;
setIsSeeking: Dispatch<SetStateAction<boolean>>;
rate: number;
setRate: (value: number) => void;
setRate: Dispatch<SetStateAction<number>>;
volume: number;
setVolume: (value: number) => void;
resizeMode: EnumValues<ResizeMode>;
setResizeMode: (value: EnumValues<ResizeMode>) => void;
setResizeMode: Dispatch<SetStateAction<EnumValues<ResizeMode>>>;
isLoading: boolean;
srcListId: number;
useCache: boolean;
setUseCache: (value: boolean) => void;
setUseCache: Dispatch<SetStateAction<boolean>>;
paused: boolean;
setPaused: (value: boolean) => void;
setPaused: Dispatch<SetStateAction<boolean>>;
repeat: boolean;
setRepeat: (value: boolean) => void;
setRepeat: Dispatch<SetStateAction<boolean>>;
poster: string | undefined;
setPoster: (value: string | undefined) => void;
setPoster: Dispatch<SetStateAction<string | undefined>>;
muted: boolean;
setMuted: (value: boolean) => void;
setMuted: Dispatch<SetStateAction<boolean>>;
currentTime: number;
duration: number;
isSeeking: boolean;
@ -81,11 +86,8 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
channelUp,
channelDown,
setFullscreen,
fullscreen,
setControls,
controls,
setDecoration,
decoration,
setShowNotificationControls,
showNotificationControls,
setSelectedAudioTrack,
@ -141,21 +143,18 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
}, []);
const toggleFullscreen = () => {
setFullscreen(!fullscreen);
setFullscreen(prev => !prev);
};
const toggleControls = () => {
setControls(!controls);
setControls(prev => !prev);
};
const toggleDecoration = () => {
setDecoration(!decoration);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
ref.current?.setFullScreen(!decoration);
const openDecoration = () => {
typeof ref !== 'function' && ref?.current?.setFullScreen(true);
};
const toggleShowNotificationControls = () => {
setShowNotificationControls(!showNotificationControls);
setShowNotificationControls(prev => !prev);
};
const onSelectedAudioTrackChange = (itemValue: string) => {
@ -197,9 +196,7 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
const videoSeek = (position: number) => {
setIsSeeking(true);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
ref.current?.seek(position);
typeof ref !== 'function' && ref?.current?.seek(position);
};
const onRateSelected = (value: number) => {
@ -214,15 +211,16 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
setResizeMode(value);
};
const toggleCache = () => setUseCache(!useCache);
const toggleCache = () => setUseCache(prev => !prev);
const togglePause = () => setPaused(!paused);
const togglePause = () => setPaused(prev => !prev);
const toggleRepeat = () => setRepeat(!repeat);
const toggleRepeat = () => setRepeat(prev => !prev);
const togglePoster = () => setPoster(poster ? undefined : samplePoster);
const togglePoster = () =>
setPoster(prev => (prev ? undefined : samplePoster));
const toggleMuted = () => setMuted(!muted);
const toggleMuted = () => setMuted(prev => !prev);
return (
<>
@ -270,7 +268,7 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
unselectedText="loop disable"
/>
<ToggleControl onPress={toggleFullscreen} text="fullscreen" />
<ToggleControl onPress={toggleDecoration} text="decoration" />
<ToggleControl onPress={openDecoration} text="decoration" />
<ToggleControl
isSelected={!!poster}
onPress={togglePoster}
@ -315,9 +313,8 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
<ToggleControl
isSelected={paused}
onPress={() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
ref.current
typeof ref !== 'function' &&
ref?.current
?.save({})
?.then((response: unknown) => {
console.log('Downloaded URI', response);

View File

@ -1,6 +1,6 @@
import {Picker} from '@react-native-picker/picker';
import {Text} from 'react-native';
import {TextTrack, SelectedTrack} from 'react-native-video';
import type {TextTrack, SelectedTrack} from 'react-native-video';
import styles from '../styles';
import React from 'react';

View File

@ -2,7 +2,7 @@ import React, {FC, memo} from 'react';
import {Text, TouchableOpacity, View} from 'react-native';
import styles from '../styles.tsx';
import {srcList} from '../constants';
import {AdditionalSourceInfo} from '../types';
import {type AdditionalSourceInfo} from '../types';
type Props = {
srcListId: number;

View File

@ -1,9 +1,9 @@
import {Picker} from '@react-native-picker/picker';
import {Text} from 'react-native';
import {
SelectedVideoTrack,
SelectedVideoTrackType,
VideoTrack,
type SelectedVideoTrack,
type VideoTrack,
} from 'react-native-video';
import styles from '../styles';
import React from 'react';