-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
Copy pathindex.tsx
108 lines (93 loc) · 4.23 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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';
import {usePlaybackContext} from '@components/VideoPlayerContexts/PlaybackContext';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import useThumbnailDimensions from '@hooks/useThumbnailDimensions';
import useWindowDimensions from '@hooks/useWindowDimensions';
import VideoPlayerThumbnail from './VideoPlayerThumbnail';
type VideoDimensions = {
width: number;
height: number;
};
type VideoPlayerPreviewProps = {
/** Url to a video. */
videoUrl: string;
/** reportID of the video */
reportID: string;
/** Dimension of a video. */
videoDimensions: VideoDimensions;
/** Duration of a video. */
videoDuration: number;
/** Url to a thumbnail image. */
thumbnailUrl?: string;
/** Name of a video file. */
fileName: string;
/** Callback executed when modal is pressed. */
onShowModalPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise<void>;
};
function VideoPlayerPreview({videoUrl, thumbnailUrl, reportID, fileName, videoDimensions, videoDuration, onShowModalPress}: VideoPlayerPreviewProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {currentlyPlayingURL, currentlyPlayingURLReportID, updateCurrentlyPlayingURL} = usePlaybackContext();
const {isSmallScreenWidth} = useWindowDimensions();
const [isThumbnail, setIsThumbnail] = useState(true);
const [measuredDimensions, setMeasuredDimensions] = useState(videoDimensions);
const {thumbnailDimensionsStyles} = useThumbnailDimensions(measuredDimensions.width, measuredDimensions.height);
// `onVideoLoaded` is passed to VideoPlayerPreview's `Video` element which is displayed only on web.
// VideoReadyForDisplayEvent type is lacking srcElement, that's why it's added here
const onVideoLoaded = (event: VideoReadyForDisplayEvent & {srcElement: HTMLVideoElement}) => {
setMeasuredDimensions({width: event.srcElement.videoWidth, height: event.srcElement.videoHeight});
};
const handleOnPress = () => {
updateCurrentlyPlayingURL(videoUrl);
if (isSmallScreenWidth) {
onShowModalPress();
}
};
useEffect(() => {
if (videoUrl !== currentlyPlayingURL || reportID !== currentlyPlayingURLReportID) {
return;
}
setIsThumbnail(false);
}, [currentlyPlayingURL, currentlyPlayingURLReportID, updateCurrentlyPlayingURL, videoUrl, reportID]);
return (
<View style={[styles.webViewStyles.tagStyles.video, thumbnailDimensionsStyles]}>
{isSmallScreenWidth || isThumbnail ? (
<VideoPlayerThumbnail
thumbnailUrl={thumbnailUrl}
onPress={handleOnPress}
accessibilityLabel={fileName}
/>
) : (
<View style={styles.flex1}>
<VideoPlayer
url={videoUrl}
onVideoLoaded={onVideoLoaded as (event: VideoReadyForDisplayEvent) => void}
videoDuration={videoDuration}
shouldUseSmallVideoControls
style={[styles.w100, styles.h100]}
isPreview
videoPlayerStyle={styles.videoPlayerPreview}
/>
<View style={[styles.pAbsolute, styles.w100]}>
<IconButton
src={Expensicons.Expand}
style={[styles.videoExpandButton]}
tooltipText={translate('videoPlayer.expand')}
onPress={onShowModalPress}
small
/>
</View>
</View>
)}
</View>
);
}
VideoPlayerPreview.displayName = 'VideoPlayerPreview';
export default VideoPlayerPreview;