Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS migration] Migrate VideoPlayer component files to TypeScript #37613

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,42 +1,23 @@
import PropTypes from 'prop-types';
import React from 'react';
import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native';
import Icon from '@components/Icon';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import Tooltip from '@components/Tooltip';
import useThemeStyles from '@hooks/useThemeStyles';
import stylePropTypes from '@styles/stylePropTypes';

const propTypes = {
// use IconAsset as soon as it will be migrated to TS
// eslint-disable-next-line react/forbid-prop-types
src: PropTypes.any.isRequired,

onPress: PropTypes.func,

fill: PropTypes.string,

tooltipText: PropTypes.string,

style: stylePropTypes,

hoverStyle: stylePropTypes,

small: PropTypes.bool,

shouldForceRenderingTooltipBelow: PropTypes.bool,
};

const defaultProps = {
fill: 'white',
onPress: () => {},
style: {},
hoverStyle: {},
small: false,
tooltipText: '',
shouldForceRenderingTooltipBelow: false,
import type IconAsset from '@src/types/utils/IconAsset';

type IconButtonProps = {
src: IconAsset;
onPress?: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise<void>;
fill?: string;
tooltipText?: string;
style?: StyleProp<ViewStyle>;
hoverStyle?: StyleProp<ViewStyle>;
small?: boolean;
shouldForceRenderingTooltipBelow?: boolean;
};

function IconButton({src, fill, onPress, style, hoverStyle, tooltipText, small, shouldForceRenderingTooltipBelow}) {
function IconButton({src, fill = 'white', onPress, style, hoverStyle, tooltipText = '', small = false, shouldForceRenderingTooltipBelow = false}: IconButtonProps) {
const styles = useThemeStyles();
return (
<Tooltip
Expand All @@ -59,8 +40,6 @@ function IconButton({src, fill, onPress, style, hoverStyle, tooltipText, small,
);
}

IconButton.propTypes = propTypes;
IconButton.defaultProps = defaultProps;
IconButton.displayName = 'IconButton';

export default IconButton;
6 changes: 3 additions & 3 deletions src/components/VideoPlayer/VideoPlayerControls/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type VideoPlayerControlsProps = {
url: string;

/** Ref for video player. */
videoPlayerRef: MutableRefObject<Video>;
videoPlayerRef: MutableRefObject<Video | null>;

/** Is video playing. */
isPlaying: boolean;
Expand Down Expand Up @@ -60,12 +60,12 @@ function VideoPlayerControls({duration, position, url, videoPlayerRef, isPlaying
const enterFullScreenMode = useCallback(() => {
isFullScreenRef.current = true;
updateCurrentlyPlayingURL(url);
videoPlayerRef.current.presentFullscreenPlayer();
videoPlayerRef.current?.presentFullscreenPlayer();
}, [isFullScreenRef, updateCurrentlyPlayingURL, url, videoPlayerRef]);

const seekPosition = useCallback(
(newPosition: number) => {
videoPlayerRef.current.setStatusAsync({positionMillis: newPosition});
videoPlayerRef.current?.setStatusAsync({positionMillis: newPosition});
},
[videoPlayerRef],
);
Expand Down
19 changes: 0 additions & 19 deletions src/components/VideoPlayer/index.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import React, {forwardRef} from 'react';
import React from 'react';
import CONST from '@src/CONST';
import BaseVideoPlayer from './BaseVideoPlayer';
import {videoPlayerDefaultProps, videoPlayerPropTypes} from './propTypes';
import type {VideoPlayerProps} from './types';

function VideoPlayer({videoControlsStyle, ...props}, ref) {
function VideoPlayer({videoControlsStyle, ...props}: VideoPlayerProps) {
return (
<BaseVideoPlayer
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
isVideoHovered
shouldUseSharedVideoElement={false}
videoControlsStyle={[{bottom: CONST.VIDEO_PLAYER.CONTROLS_POSITION.NATIVE}, videoControlsStyle]}
ref={ref}
/>
);
}

VideoPlayer.displayName = 'VideoPlayer';
VideoPlayer.propTypes = videoPlayerPropTypes;
VideoPlayer.defaultProps = videoPlayerDefaultProps;

export default forwardRef(VideoPlayer);
export default VideoPlayer;
16 changes: 16 additions & 0 deletions src/components/VideoPlayer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import BaseVideoPlayer from './BaseVideoPlayer';
import type {VideoPlayerProps} from './types';

function VideoPlayer(props: VideoPlayerProps) {
return (
<BaseVideoPlayer
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
);
}

VideoPlayer.displayName = 'VideoPlayer';

export default VideoPlayer;
57 changes: 0 additions & 57 deletions src/components/VideoPlayer/propTypes.js

This file was deleted.

29 changes: 29 additions & 0 deletions src/components/VideoPlayer/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type {Video} from 'expo-av';
import type {AVPlaybackStatus} from 'expo-av/build/AV';
import type {VideoFullscreenUpdateEvent, VideoReadyForDisplayEvent} from 'expo-av/build/Video.types';
import type {StyleProp, ViewStyle} from 'react-native';

type VideoWithOnFullScreenUpdate = Video & {_onFullscreenUpdate: (event: VideoFullscreenUpdateEvent) => void};

type VideoPlayerProps = {
url: string;
onVideoLoaded?: (event: VideoReadyForDisplayEvent) => void;
resizeMode?: string;
isLooping?: boolean;
// style for the whole video player component
style: StyleProp<ViewStyle>;
// style for the video player inside the component
videoPlayerStyle?: StyleProp<ViewStyle>;
// style for the video element inside the video player
videoStyle?: StyleProp<ViewStyle>;
videoControlsStyle?: StyleProp<ViewStyle>;
videoDuration: number;
shouldUseSharedVideoElement?: boolean;
shouldUseSmallVideoControls?: boolean;
shouldShowVideoControls?: boolean;
isVideoHovered?: boolean;
onFullscreenUpdate?: (event: VideoFullscreenUpdateEvent) => void;
onPlaybackStatusUpdate?: (status: AVPlaybackStatus) => void;
};

export type {VideoPlayerProps, VideoWithOnFullScreenUpdate};
13 changes: 7 additions & 6 deletions src/components/VideoPlayerContexts/PlaybackContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {AVPlaybackStatusToSet, Video} from 'expo-av';
import type {AVPlaybackStatusToSet} from 'expo-av';
import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
import type {View} from 'react-native';
import type {VideoWithOnFullScreenUpdate} from '@components/VideoPlayer/types';
import useCurrentReportID from '@hooks/useCurrentReportID';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import type {PlaybackContext, StatusCallback} from './types';
Expand All @@ -9,11 +10,11 @@ const Context = React.createContext<PlaybackContext | null>(null);

function PlaybackContextProvider({children}: ChildrenProps) {
const [currentlyPlayingURL, setCurrentlyPlayingURL] = useState<string | null>(null);
const [sharedElement, setSharedElement] = useState<View | null>(null);
const [originalParent, setOriginalParent] = useState<View | null>(null);
const currentVideoPlayerRef = useRef<Video | null>(null);
const [sharedElement, setSharedElement] = useState<View | HTMLDivElement | null>(null);
const [originalParent, setOriginalParent] = useState<View | HTMLDivElement | null>(null);
const currentVideoPlayerRef = useRef<VideoWithOnFullScreenUpdate | null>(null);
const {currentReportID} = useCurrentReportID() ?? {};
const videoResumeTryNumber = useRef(0);
const videoResumeTryNumber = useRef<number>(0);

const pauseVideo = useCallback(() => {
currentVideoPlayerRef.current?.setStatusAsync?.({shouldPlay: false});
Expand Down Expand Up @@ -48,7 +49,7 @@ function PlaybackContextProvider({children}: ChildrenProps) {
);

const shareVideoPlayerElements = useCallback(
(ref: Video, parent: View, child: View, isUploading: boolean) => {
(ref: VideoWithOnFullScreenUpdate | null, parent: View | HTMLDivElement | null, child: View | HTMLDivElement | null, isUploading: boolean) => {
currentVideoPlayerRef.current = ref;
setOriginalParent(parent);
setSharedElement(child);
Expand Down
11 changes: 6 additions & 5 deletions src/components/VideoPlayerContexts/types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import type {Video} from 'expo-av';
import type {MutableRefObject} from 'react';
import type {View} from 'react-native';
import type {SharedValue} from 'react-native-reanimated';
import type {PopoverMenuItem} from '@components/PopoverMenu';
import type {VideoWithOnFullScreenUpdate} from '@components/VideoPlayer/types';
import type WindowDimensions from '@hooks/useWindowDimensions/types';
import type CONST from '@src/CONST';

type PlaybackContext = {
updateCurrentlyPlayingURL: (url: string | null) => void;
currentlyPlayingURL: string | null;
originalParent: View | null;
sharedElement: View | null;
currentVideoPlayerRef: MutableRefObject<Video | null>;
shareVideoPlayerElements: (ref: Video, parent: View, child: View, isUploading: boolean) => void;
originalParent: View | HTMLDivElement | null;
sharedElement: View | HTMLDivElement | null;
videoResumeTryNumber: MutableRefObject<number>;
currentVideoPlayerRef: MutableRefObject<VideoWithOnFullScreenUpdate | null>;
shareVideoPlayerElements: (ref: VideoWithOnFullScreenUpdate | null, parent: View | HTMLDivElement | null, child: View | HTMLDivElement | null, isUploading: boolean) => void;
playVideo: () => void;
pauseVideo: () => void;
checkVideoPlaying: (statusCallback: StatusCallback) => void;
Expand Down
1 change: 0 additions & 1 deletion src/components/VideoPlayerPreview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ function VideoPlayerPreview({videoUrl, thumbnailUrl, fileName, videoDimensions,
<>
<VideoPlayer
url={videoUrl}
onOpenInModalButtonPress={onShowModalPress}
onVideoLoaded={onVideoLoaded as (event: VideoReadyForDisplayEvent) => void}
videoDuration={videoDuration}
shouldUseSmallVideoControls
Expand Down
Loading