From 7ef3d289fc3b178c48d5b3dff0e7b85d1888460c Mon Sep 17 00:00:00 2001 From: smelaa Date: Tue, 27 Feb 2024 18:26:51 +0100 Subject: [PATCH 01/16] VideoPlayerThumbnail migreated to ts --- ...rThumbnail.js => VideoPlayerThumbnail.tsx} | 22 +++---------------- src/components/VideoPlayerPreview/types.ts | 9 ++++++++ 2 files changed, 12 insertions(+), 19 deletions(-) rename src/components/VideoPlayerPreview/{VideoPlayerThumbnail.js => VideoPlayerThumbnail.tsx} (78%) create mode 100644 src/components/VideoPlayerPreview/types.ts diff --git a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.js b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx similarity index 78% rename from src/components/VideoPlayerPreview/VideoPlayerThumbnail.js rename to src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx index 595442c317d5..896c8778ba06 100644 --- a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.js +++ b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import Icon from '@components/Icon'; @@ -12,20 +11,9 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; +import VideoPlayerThumbnailProps from './types'; -const propTypes = { - onPress: PropTypes.func.isRequired, - - accessibilityLabel: PropTypes.string.isRequired, - - thumbnailUrl: PropTypes.string, -}; - -const defaultProps = { - thumbnailUrl: undefined, -}; - -function VideoPlayerThumbnail({thumbnailUrl, onPress, accessibilityLabel}) { +function VideoPlayerThumbnail({thumbnailUrl = undefined, onPress, accessibilityLabel}: VideoPlayerThumbnailProps) { const styles = useThemeStyles(); return ( @@ -48,9 +36,7 @@ function VideoPlayerThumbnail({thumbnailUrl, onPress, accessibilityLabel}) { onPress={onPress} onPressIn={() => DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} onPressOut={() => ControlSelection.unblock()} - onLongPress={(event) => - showContextMenuForReport(event, anchor, (report && report.reportID) || '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report)) - } + onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))} > void; + accessibilityLabel: string; +}; + +export default VideoPlayerThumbnailProps; From 1a7099077402761a95b75b7f997c349be30ddbc5 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 28 Feb 2024 15:00:14 +0100 Subject: [PATCH 02/16] Migration of VideoPlayerPreview --- .../VideoPlayerThumbnail.tsx | 2 +- .../{index.js => index.tsx} | 43 ++++++------------- src/components/VideoPlayerPreview/types.ts | 21 ++++++++- 3 files changed, 33 insertions(+), 33 deletions(-) rename src/components/VideoPlayerPreview/{index.js => index.tsx} (73%) diff --git a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx index 896c8778ba06..c7342a0d80e6 100644 --- a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx +++ b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx @@ -11,7 +11,7 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import VideoPlayerThumbnailProps from './types'; +import type {VideoPlayerThumbnailProps} from './types'; function VideoPlayerThumbnail({thumbnailUrl = undefined, onPress, accessibilityLabel}: VideoPlayerThumbnailProps) { const styles = useThemeStyles(); diff --git a/src/components/VideoPlayerPreview/index.js b/src/components/VideoPlayerPreview/index.tsx similarity index 73% rename from src/components/VideoPlayerPreview/index.js rename to src/components/VideoPlayerPreview/index.tsx index 252bc53fc839..2bc370711c00 100644 --- a/src/components/VideoPlayerPreview/index.js +++ b/src/components/VideoPlayerPreview/index.tsx @@ -1,4 +1,4 @@ -import PropTypes from 'prop-types'; +import type {VideoReadyForDisplayEvent} from 'expo-av'; import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -10,32 +10,17 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useThumbnailDimensions from '@hooks/useThumbnailDimensions'; import useWindowDimensions from '@hooks/useWindowDimensions'; import CONST from '@src/CONST'; +import type {VideoPlayerPreviewProps} from './types'; import VideoPlayerThumbnail from './VideoPlayerThumbnail'; -const propTypes = { - videoUrl: PropTypes.string.isRequired, - - videoDimensions: PropTypes.shape({ - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - }), - - videoDuration: PropTypes.number, - - thumbnailUrl: PropTypes.string, - - fileName: PropTypes.string.isRequired, - - onShowModalPress: PropTypes.func.isRequired, -}; - -const defaultProps = { - videoDimensions: CONST.VIDEO_PLAYER.DEFAULT_VIDEO_DIMENSIONS, - thumbnailUrl: undefined, - videoDuration: 0, -}; - -function VideoPlayerPreview({videoUrl, thumbnailUrl, fileName, videoDimensions, videoDuration, onShowModalPress}) { +function VideoPlayerPreview({ + videoUrl, + thumbnailUrl = undefined, + fileName, + videoDimensions = CONST.VIDEO_PLAYER.DEFAULT_VIDEO_DIMENSIONS, + videoDuration = 0, + onShowModalPress, +}: VideoPlayerPreviewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const {currentlyPlayingURL, updateCurrentlyPlayingURL} = usePlaybackContext(); @@ -44,8 +29,8 @@ function VideoPlayerPreview({videoUrl, thumbnailUrl, fileName, videoDimensions, const [measuredDimensions, setMeasuredDimensions] = useState(videoDimensions); const {thumbnailDimensionsStyles} = useThumbnailDimensions(measuredDimensions.width, measuredDimensions.height); - const onVideoLoaded = (e) => { - setMeasuredDimensions({width: e.srcElement.videoWidth, height: e.srcElement.videoHeight}); + const onVideoLoaded = (event: VideoReadyForDisplayEvent & {srcElement: HTMLVideoElement}) => { + setMeasuredDimensions({width: event.srcElement.videoWidth, height: event.srcElement.videoHeight}); }; const handleOnPress = () => { @@ -75,7 +60,7 @@ function VideoPlayerPreview({videoUrl, thumbnailUrl, fileName, videoDimensions, void} videoDuration={videoDuration} shouldUseSmallVideoControls style={[styles.w100, styles.h100]} @@ -94,8 +79,6 @@ function VideoPlayerPreview({videoUrl, thumbnailUrl, fileName, videoDimensions, ); } -VideoPlayerPreview.propTypes = propTypes; -VideoPlayerPreview.defaultProps = defaultProps; VideoPlayerPreview.displayName = 'VideoPlayerPreview'; export default VideoPlayerPreview; diff --git a/src/components/VideoPlayerPreview/types.ts b/src/components/VideoPlayerPreview/types.ts index 2d1d1557e00a..4b4204b9f852 100644 --- a/src/components/VideoPlayerPreview/types.ts +++ b/src/components/VideoPlayerPreview/types.ts @@ -2,8 +2,25 @@ import type {GestureResponderEvent} from 'react-native'; type VideoPlayerThumbnailProps = { thumbnailUrl: string | undefined; - onPress: (event?: GestureResponderEvent | KeyboardEvent) => void; + onPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; accessibilityLabel: string; }; -export default VideoPlayerThumbnailProps; +type VideoPlayerPreviewProps = { + videoUrl: string; + + videoDimensions: { + width: number; + height: number; + }; + + videoDuration: number; + + thumbnailUrl?: string; + + fileName: string; + + onShowModalPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; +}; + +export type {VideoPlayerThumbnailProps, VideoPlayerPreviewProps}; From aed45f85048d5eac559b893cff6c81e4a04c5b83 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 28 Feb 2024 16:44:39 +0100 Subject: [PATCH 03/16] Addressing review comments --- .../VideoPlayerThumbnail.tsx | 10 +++++-- src/components/VideoPlayerPreview/index.tsx | 29 +++++++++++++------ src/components/VideoPlayerPreview/types.ts | 26 ----------------- 3 files changed, 28 insertions(+), 37 deletions(-) delete mode 100644 src/components/VideoPlayerPreview/types.ts diff --git a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx index c7342a0d80e6..aa4b06760f0d 100644 --- a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx +++ b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx @@ -1,5 +1,6 @@ import React from 'react'; import {View} from 'react-native'; +import type {GestureResponderEvent} from 'react-native'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import Image from '@components/Image'; @@ -11,9 +12,14 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import type {VideoPlayerThumbnailProps} from './types'; -function VideoPlayerThumbnail({thumbnailUrl = undefined, onPress, accessibilityLabel}: VideoPlayerThumbnailProps) { +type VideoPlayerThumbnailProps = { + thumbnailUrl: string | undefined; + onPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; + accessibilityLabel: string; +}; + +function VideoPlayerThumbnail({thumbnailUrl, onPress, accessibilityLabel}: VideoPlayerThumbnailProps) { const styles = useThemeStyles(); return ( diff --git a/src/components/VideoPlayerPreview/index.tsx b/src/components/VideoPlayerPreview/index.tsx index 2bc370711c00..391596fa6961 100644 --- a/src/components/VideoPlayerPreview/index.tsx +++ b/src/components/VideoPlayerPreview/index.tsx @@ -1,6 +1,7 @@ import type {VideoReadyForDisplayEvent} from 'expo-av'; import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; +import type {GestureResponderEvent} from 'react-native'; import * as Expensicons from '@components/Icon/Expensicons'; import VideoPlayer from '@components/VideoPlayer'; import IconButton from '@components/VideoPlayer/IconButton'; @@ -10,17 +11,23 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useThumbnailDimensions from '@hooks/useThumbnailDimensions'; import useWindowDimensions from '@hooks/useWindowDimensions'; import CONST from '@src/CONST'; -import type {VideoPlayerPreviewProps} from './types'; import VideoPlayerThumbnail from './VideoPlayerThumbnail'; -function VideoPlayerPreview({ - videoUrl, - thumbnailUrl = undefined, - fileName, - videoDimensions = CONST.VIDEO_PLAYER.DEFAULT_VIDEO_DIMENSIONS, - videoDuration = 0, - onShowModalPress, -}: VideoPlayerPreviewProps) { +type VideoDimensions = { + width: number; + height: number; +}; + +type VideoPlayerPreviewProps = { + videoUrl: string; + videoDimensions: VideoDimensions; + videoDuration: number; + thumbnailUrl?: string; + fileName: string; + onShowModalPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; +}; + +function VideoPlayerPreview({videoUrl, thumbnailUrl, fileName, videoDimensions = CONST.VIDEO_PLAYER.DEFAULT_VIDEO_DIMENSIONS, videoDuration = 0, onShowModalPress}: VideoPlayerPreviewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const {currentlyPlayingURL, updateCurrentlyPlayingURL} = usePlaybackContext(); @@ -29,6 +36,10 @@ function VideoPlayerPreview({ const [measuredDimensions, setMeasuredDimensions] = useState(videoDimensions); const {thumbnailDimensionsStyles} = useThumbnailDimensions(measuredDimensions.width, measuredDimensions.height); + // onVideoLoaded is passed to VideoPlayer, then BaseVideoPlayer and then as a prop onReadyForDisplay of Video. + // Therefore, the type of the event should be VideoReadyForDisplayEvent, however it does not include srcElement in its definition, + // as srcElement is present only for web implementation of Video. VideoPlayerPreview is used only for web. + const onVideoLoaded = (event: VideoReadyForDisplayEvent & {srcElement: HTMLVideoElement}) => { setMeasuredDimensions({width: event.srcElement.videoWidth, height: event.srcElement.videoHeight}); }; diff --git a/src/components/VideoPlayerPreview/types.ts b/src/components/VideoPlayerPreview/types.ts deleted file mode 100644 index 4b4204b9f852..000000000000 --- a/src/components/VideoPlayerPreview/types.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type {GestureResponderEvent} from 'react-native'; - -type VideoPlayerThumbnailProps = { - thumbnailUrl: string | undefined; - onPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; - accessibilityLabel: string; -}; - -type VideoPlayerPreviewProps = { - videoUrl: string; - - videoDimensions: { - width: number; - height: number; - }; - - videoDuration: number; - - thumbnailUrl?: string; - - fileName: string; - - onShowModalPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; -}; - -export type {VideoPlayerThumbnailProps, VideoPlayerPreviewProps}; From d176eaf34b3767527809fbec08642fccc023f5d7 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 28 Feb 2024 17:30:02 +0100 Subject: [PATCH 04/16] VideoPopovermenu migrated to ts --- src/components/Popover/types.ts | 2 +- src/components/PopoverMenu.tsx | 2 +- .../VideoPopoverMenu/{index.js => index.tsx} | 32 +++++++------------ 3 files changed, 14 insertions(+), 22 deletions(-) rename src/components/VideoPopoverMenu/{index.js => index.tsx} (54%) diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index e06037f47b63..fc73f6fc5d6b 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -20,7 +20,7 @@ type PopoverProps = BaseModalProps & anchorAlignment?: AnchorAlignment; /** The anchor ref of the popover */ - anchorRef: RefObject; + anchorRef?: RefObject; /** Whether disable the animations */ disableAnimation?: boolean; diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index 4ee070e19893..d59153e680e7 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -51,7 +51,7 @@ type PopoverMenuProps = Partial & { anchorPosition: AnchorPosition; /** Ref of the anchor */ - anchorRef: RefObject; + anchorRef?: RefObject; /** Where the popover should be positioned relative to the anchor points. */ anchorAlignment?: AnchorAlignment; diff --git a/src/components/VideoPopoverMenu/index.js b/src/components/VideoPopoverMenu/index.tsx similarity index 54% rename from src/components/VideoPopoverMenu/index.js rename to src/components/VideoPopoverMenu/index.tsx index 01aaa8e35174..41f60452e0ad 100644 --- a/src/components/VideoPopoverMenu/index.js +++ b/src/components/VideoPopoverMenu/index.tsx @@ -1,28 +1,23 @@ -import PropTypes from 'prop-types'; import React from 'react'; +import type {PopoverMenuItem} from '@components/PopoverMenu'; import PopoverMenu from '@components/PopoverMenu'; import {useVideoPopoverMenuContext} from '@components/VideoPlayerContexts/VideoPopoverMenuContext'; +import type {AnchorPosition} from '@styles/index'; -const propTypes = { - isPopoverVisible: PropTypes.bool, - - hidePopover: PropTypes.func, - - anchorPosition: PropTypes.shape({ - horizontal: PropTypes.number.isRequired, - vertical: PropTypes.number.isRequired, - }), +type VideoPopoverMenuProps = { + isPopoverVisible: boolean; + hidePopover: (selectedItem?: PopoverMenuItem, index?: number) => void; + anchorPosition: AnchorPosition; }; -const defaultProps = { - isPopoverVisible: false, - anchorPosition: { + +function VideoPopoverMenu({ + isPopoverVisible = false, + hidePopover = () => {}, + anchorPosition = { horizontal: 0, vertical: 0, }, - hidePopover: () => {}, -}; - -function VideoPopoverMenu({isPopoverVisible, hidePopover, anchorPosition}) { +}: VideoPopoverMenuProps) { const {menuItems} = useVideoPopoverMenuContext(); return ( @@ -36,9 +31,6 @@ function VideoPopoverMenu({isPopoverVisible, hidePopover, anchorPosition}) { /> ); } - -VideoPopoverMenu.propTypes = propTypes; -VideoPopoverMenu.defaultProps = defaultProps; VideoPopoverMenu.displayName = 'VideoPopoverMenu'; export default VideoPopoverMenu; From 03eae4166948392968284a6c800fd892b2afc67c Mon Sep 17 00:00:00 2001 From: smelaa Date: Thu, 29 Feb 2024 11:41:04 +0100 Subject: [PATCH 05/16] ProgressBar migrated to ts --- .../ProgressBar/{index.js => index.tsx} | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) rename src/components/VideoPlayer/VideoPlayerControls/ProgressBar/{index.js => index.tsx} (73%) diff --git a/src/components/VideoPlayer/VideoPlayerControls/ProgressBar/index.js b/src/components/VideoPlayer/VideoPlayerControls/ProgressBar/index.tsx similarity index 73% rename from src/components/VideoPlayer/VideoPlayerControls/ProgressBar/index.js rename to src/components/VideoPlayer/VideoPlayerControls/ProgressBar/index.tsx index c6eb1a179726..72df96410e1c 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/ProgressBar/index.js +++ b/src/components/VideoPlayer/VideoPlayerControls/ProgressBar/index.tsx @@ -1,25 +1,22 @@ -import PropTypes from 'prop-types'; import React, {useEffect, useState} from 'react'; +import type {LayoutChangeEvent, ViewStyle} from 'react-native'; +import type {GestureStateChangeEvent, GestureUpdateEvent, PanGestureChangeEventPayload, PanGestureHandlerEventPayload} from 'react-native-gesture-handler'; import {Gesture, GestureDetector} from 'react-native-gesture-handler'; import Animated, {runOnJS, useAnimatedStyle, useSharedValue} from 'react-native-reanimated'; import {usePlaybackContext} from '@components/VideoPlayerContexts/PlaybackContext'; import useThemeStyles from '@hooks/useThemeStyles'; -const propTypes = { - duration: PropTypes.number.isRequired, - - position: PropTypes.number.isRequired, - - seekPosition: PropTypes.func.isRequired, +type ProgressBarProps = { + duration: number; + position: number; + seekPosition: (newPosition: number) => void; }; -const defaultProps = {}; - -function getProgress(currentPosition, maxPosition) { +function getProgress(currentPosition: number, maxPosition: number) { return Math.min(Math.max((currentPosition / maxPosition) * 100, 0), 100); } -function ProgressBar({duration, position, seekPosition}) { +function ProgressBar({duration, position, seekPosition}: ProgressBarProps) { const styles = useThemeStyles(); const {pauseVideo, playVideo, checkVideoPlaying} = usePlaybackContext(); const [sliderWidth, setSliderWidth] = useState(1); @@ -27,18 +24,18 @@ function ProgressBar({duration, position, seekPosition}) { const progressWidth = useSharedValue(0); const wasVideoPlayingOnCheck = useSharedValue(false); - const onCheckVideoPlaying = (isPlaying) => { + const onCheckVideoPlaying = (isPlaying: boolean) => { wasVideoPlayingOnCheck.value = isPlaying; }; - const progressBarInteraction = (event) => { + const progressBarInteraction = (event: GestureUpdateEvent | GestureStateChangeEvent) => { const progress = getProgress(event.x, sliderWidth); progressWidth.value = progress; runOnJS(seekPosition)((progress * duration) / 100); }; - const onSliderLayout = (e) => { - setSliderWidth(e.nativeEvent.layout.width); + const onSliderLayout = (event: LayoutChangeEvent) => { + setSliderWidth(event.nativeEvent.layout.width); }; const pan = Gesture.Pan() @@ -66,7 +63,7 @@ function ProgressBar({duration, position, seekPosition}) { progressWidth.value = getProgress(position, duration); }, [duration, isSliderPressed, position, progressWidth]); - const progressBarStyle = useAnimatedStyle(() => ({width: `${progressWidth.value}%`})); + const progressBarStyle = useAnimatedStyle(() => ({width: `${progressWidth.value}%`} as ViewStyle)); return ( @@ -85,8 +82,6 @@ function ProgressBar({duration, position, seekPosition}) { ); } -ProgressBar.propTypes = propTypes; -ProgressBar.defaultProps = defaultProps; ProgressBar.displayName = 'ProgressBar'; export default ProgressBar; From 07947cd4d3a64315362ac5199a27cb620ddc2a86 Mon Sep 17 00:00:00 2001 From: smelaa Date: Thu, 29 Feb 2024 13:44:08 +0100 Subject: [PATCH 06/16] VolumeButton migrated to ts --- .../VolumeButton/{index.js => index.tsx} | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) rename src/components/VideoPlayer/VideoPlayerControls/VolumeButton/{index.js => index.tsx} (82%) diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx similarity index 82% rename from src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js rename to src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx index 45f47eb87c36..b6e5d3af8003 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx @@ -1,6 +1,7 @@ -import PropTypes from 'prop-types'; import React, {memo, useCallback, useState} from 'react'; +import type {LayoutChangeEvent, ViewStyle} from 'react-native'; import {View} from 'react-native'; +import type {GestureStateChangeEvent, GestureUpdateEvent, PanGestureChangeEventPayload, PanGestureHandlerEventPayload} from 'react-native-gesture-handler'; import {Gesture, GestureDetector} from 'react-native-gesture-handler'; import Animated, {runOnJS, useAnimatedStyle, useDerivedValue} from 'react-native-reanimated'; import Hoverable from '@components/Hoverable'; @@ -10,18 +11,13 @@ import {useVolumeContext} from '@components/VideoPlayerContexts/VolumeContext'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as NumberUtils from '@libs/NumberUtils'; -import stylePropTypes from '@styles/stylePropTypes'; -const propTypes = { - style: stylePropTypes.isRequired, - small: PropTypes.bool, +type VolumeButtonProps = { + style: ViewStyle; + small: boolean; }; -const defaultProps = { - small: false, -}; - -const getVolumeIcon = (volume) => { +const getVolumeIcon = (volume: number) => { if (volume === 0) { return Expensicons.Mute; } @@ -31,7 +27,7 @@ const getVolumeIcon = (volume) => { return Expensicons.VolumeHigh; }; -function VolumeButton({style, small}) { +function VolumeButton({style, small = false}: VolumeButtonProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const {updateVolume, volume} = useVolumeContext(); @@ -39,12 +35,12 @@ function VolumeButton({style, small}) { const [volumeIcon, setVolumeIcon] = useState({icon: getVolumeIcon(volume.value)}); const [isSliderBeingUsed, setIsSliderBeingUsed] = useState(false); - const onSliderLayout = useCallback((e) => { - setSliderHeight(e.nativeEvent.layout.height); + const onSliderLayout = useCallback((event: LayoutChangeEvent) => { + setSliderHeight(event.nativeEvent.layout.height); }, []); const changeVolumeOnPan = useCallback( - (event) => { + (event: GestureStateChangeEvent | GestureUpdateEvent) => { const val = NumberUtils.roundToTwoDecimalPlaces(1 - event.y / sliderHeight); volume.value = NumberUtils.clamp(val, 0, 1); }, @@ -65,7 +61,7 @@ function VolumeButton({style, small}) { const progressBarStyle = useAnimatedStyle(() => ({height: `${volume.value * 100}%`})); - const updateIcon = useCallback((vol) => { + const updateIcon = useCallback((vol: number) => { setVolumeIcon({icon: getVolumeIcon(vol)}); }, []); @@ -98,7 +94,6 @@ function VolumeButton({style, small}) { tooltipText={volume.value === 0 ? translate('videoPlayer.unmute') : translate('videoPlayer.mute')} onPress={() => updateVolume(volume.value === 0 ? 1 : 0)} src={volumeIcon.icon} - fill={styles.white} small={small} shouldForceRenderingTooltipBelow /> @@ -108,8 +103,6 @@ function VolumeButton({style, small}) { ); } -VolumeButton.propTypes = propTypes; -VolumeButton.defaultProps = defaultProps; VolumeButton.displayName = 'VolumeButton'; export default memo(VolumeButton); From 1c8b7890fc02179c7adb9d6acc07b619c7e6807f Mon Sep 17 00:00:00 2001 From: smelaa Date: Thu, 29 Feb 2024 14:59:43 +0100 Subject: [PATCH 07/16] VideoPlayerControls migrated to ts --- .../VolumeButton/index.tsx | 2 +- .../{index.js => index.tsx} | 49 +++++++------------ 2 files changed, 18 insertions(+), 33 deletions(-) rename src/components/VideoPlayer/VideoPlayerControls/{index.js => index.tsx} (81%) diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx index b6e5d3af8003..ee93eb672774 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx @@ -14,7 +14,7 @@ import * as NumberUtils from '@libs/NumberUtils'; type VolumeButtonProps = { style: ViewStyle; - small: boolean; + small?: boolean; }; const getVolumeIcon = (volume: number) => { diff --git a/src/components/VideoPlayer/VideoPlayerControls/index.js b/src/components/VideoPlayer/VideoPlayerControls/index.tsx similarity index 81% rename from src/components/VideoPlayer/VideoPlayerControls/index.js rename to src/components/VideoPlayer/VideoPlayerControls/index.tsx index 5a926123feef..6af44a8e3dda 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/index.js +++ b/src/components/VideoPlayer/VideoPlayerControls/index.tsx @@ -1,55 +1,42 @@ -import PropTypes from 'prop-types'; +import type {Video} from 'expo-av'; +import type {MutableRefObject} from 'react'; import React, {useCallback, useMemo, useState} from 'react'; +import type {GestureResponderEvent, LayoutChangeEvent, ViewStyle} from 'react-native'; import {View} from 'react-native'; import Animated from 'react-native-reanimated'; import * as Expensicons from '@components/Icon/Expensicons'; -import refPropTypes from '@components/refPropTypes'; import Text from '@components/Text'; import IconButton from '@components/VideoPlayer/IconButton'; import convertMillisecondsToTime from '@components/VideoPlayer/utils'; import {usePlaybackContext} from '@components/VideoPlayerContexts/PlaybackContext'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import stylePropTypes from '@styles/stylePropTypes'; import CONST from '@src/CONST'; import ProgressBar from './ProgressBar'; import VolumeButton from './VolumeButton'; -const propTypes = { - duration: PropTypes.number.isRequired, - - position: PropTypes.number.isRequired, - - url: PropTypes.string.isRequired, - - videoPlayerRef: refPropTypes.isRequired, - - isPlaying: PropTypes.bool.isRequired, - +type VideoPlayerControlsProps = { + duration: number; + position: number; + url: string; + videoPlayerRef: MutableRefObject