diff --git a/lib/types/media-types.js b/lib/types/media-types.js --- a/lib/types/media-types.js +++ b/lib/types/media-types.js @@ -10,6 +10,8 @@ export type MediaType = 'photo' | 'video'; +export type EncryptedMediaType = 'encrypted_photo' | 'encrypted_video'; + export type Image = { +id: string, +uri: string, diff --git a/web/media/encrypted-multimedia.react.js b/web/media/encrypted-multimedia.react.js new file mode 100644 --- /dev/null +++ b/web/media/encrypted-multimedia.react.js @@ -0,0 +1,97 @@ +// @flow + +import * as React from 'react'; +import 'react-circular-progressbar/dist/styles.css'; +import { AlertCircle as AlertCircleIcon } from 'react-feather'; + +import type { EncryptedMediaType } from 'lib/types/media-types.js'; + +import { decryptMedia } from './encryption-utils.js'; +import css from './media.css'; +import LoadingIndicator from '../loading-indicator.react.js'; + +type Props = { + +holder: string, + +encryptionKey: string, + +type: EncryptedMediaType, +}; + +function EncryptedMultimedia(props: Props): React.Node { + const { holder, encryptionKey } = props; + + const [source, setSource] = React.useState(null); + const videoRef = React.useRef(null); + + React.useEffect(() => { + let isMounted = true, + uriToDispose; + setSource(null); + + const loadDecrypted = async () => { + const { result } = await decryptMedia(holder, encryptionKey); + if (!isMounted) { + return; + } + + if (result.success) { + const { uri } = result; + setSource({ uri }); + uriToDispose = uri; + } else { + setSource({ error: result.reason }); + } + }; + + loadDecrypted(); + + return () => { + isMounted = false; + if (uriToDispose) { + URL.revokeObjectURL(uriToDispose); + } + }; + }, [holder, encryptionKey]); + + // we need to update the video source when the source changes + // because re-rendering the element wouldn't reload parent