-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
VideoPopoverMenuContext.tsx
89 lines (78 loc) · 3.72 KB
/
VideoPopoverMenuContext.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
import React, {useCallback, useContext, useMemo, useRef, useState} from 'react';
import * as Expensicons from '@components/Icon/Expensicons';
import type {PopoverMenuItem} from '@components/PopoverMenu';
import type {VideoWithOnFullScreenUpdate} from '@components/VideoPlayer/types';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL';
import fileDownload from '@libs/fileDownload';
import CONST from '@src/CONST';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import {usePlaybackContext} from './PlaybackContext';
import type {PlaybackSpeed, VideoPopoverMenuContext} from './types';
const Context = React.createContext<VideoPopoverMenuContext | null>(null);
function VideoPopoverMenuContextProvider({children}: ChildrenProps) {
const {currentlyPlayingURL} = usePlaybackContext();
const {translate} = useLocalize();
const [currentPlaybackSpeed, setCurrentPlaybackSpeed] = useState<PlaybackSpeed>(CONST.VIDEO_PLAYER.PLAYBACK_SPEEDS[2]);
const {isOffline} = useNetwork();
const isLocalFile = currentlyPlayingURL && CONST.ATTACHMENT_LOCAL_URL_PREFIX.some((prefix) => currentlyPlayingURL.startsWith(prefix));
const videoPopoverMenuPlayerRef = useRef<VideoWithOnFullScreenUpdate | null>(null);
const updatePlaybackSpeed = useCallback(
(speed: PlaybackSpeed) => {
setCurrentPlaybackSpeed(speed);
videoPopoverMenuPlayerRef.current?.setStatusAsync?.({rate: speed});
},
[videoPopoverMenuPlayerRef],
);
const downloadAttachment = useCallback(() => {
if (videoPopoverMenuPlayerRef.current === null) {
return;
}
const {source} = videoPopoverMenuPlayerRef.current?.props ?? {};
if (typeof source === 'number' || !source) {
return;
}
const sourceURI = addEncryptedAuthTokenToURL(source.uri);
fileDownload(sourceURI);
}, [videoPopoverMenuPlayerRef]);
const menuItems = useMemo(() => {
const items: PopoverMenuItem[] = [];
if (!isOffline && !isLocalFile) {
items.push({
icon: Expensicons.Download,
text: translate('common.download'),
onSelected: () => {
downloadAttachment();
},
});
}
items.push({
icon: Expensicons.Meter,
text: translate('videoPlayer.playbackSpeed'),
subMenuItems: CONST.VIDEO_PLAYER.PLAYBACK_SPEEDS.map((speed) => ({
icon: currentPlaybackSpeed === speed ? Expensicons.Checkmark : undefined,
text: speed.toString(),
onSelected: () => {
updatePlaybackSpeed(speed);
},
shouldPutLeftPaddingWhenNoIcon: true,
})),
});
return items;
}, [currentPlaybackSpeed, downloadAttachment, translate, updatePlaybackSpeed, isOffline, isLocalFile]);
const contextValue = useMemo(
() => ({menuItems, videoPopoverMenuPlayerRef, updatePlaybackSpeed, setCurrentPlaybackSpeed}),
[menuItems, videoPopoverMenuPlayerRef, updatePlaybackSpeed, setCurrentPlaybackSpeed],
);
return <Context.Provider value={contextValue}>{children}</Context.Provider>;
}
function useVideoPopoverMenuContext() {
const videoPopooverMenuContext = useContext(Context);
if (!videoPopooverMenuContext) {
throw new Error('useVideoPopoverMenuContext must be used within a VideoPopoverMenuContext');
}
return videoPopooverMenuContext;
}
VideoPopoverMenuContextProvider.displayName = 'VideoPopoverMenuContextProvider';
export {VideoPopoverMenuContextProvider, useVideoPopoverMenuContext};