Page MenuHomePhorge

D7946.1768526320.diff
No OneTemporary

Size
2 KB
Referenced Files
None
Subscribers
None

D7946.1768526320.diff

diff --git a/web/media/loadable-video.react.js b/web/media/loadable-video.react.js
new file mode 100644
--- /dev/null
+++ b/web/media/loadable-video.react.js
@@ -0,0 +1,86 @@
+// @flow
+
+import invariant from 'invariant';
+import * as React from 'react';
+
+import type { Shape } from 'lib/types/core.js';
+
+import { decryptMedia } from './encryption-utils.js';
+import { preloadImage } from './media-utils.js';
+
+type ThumbnailSource =
+ | {
+ +thumbnailURI: string,
+ }
+ | {
+ +thumbnailHolder: string,
+ +thumbnailEncryptionKey: string,
+ };
+type Props = {
+ +uri: ?string,
+ +thumbnailSource: ThumbnailSource,
+ +thumbHashDataURL?: ?string,
+ +elementStyle?: ?Shape<CSSStyleDeclaration>,
+};
+
+function LoadableVideo(props: Props, videoRef: React.Ref<'video'>): React.Node {
+ const { uri, thumbHashDataURL, thumbnailSource, elementStyle } = props;
+ const { thumbnailURI, thumbnailHolder, thumbnailEncryptionKey } =
+ thumbnailSource;
+
+ const [thumbnailImage, setThumbnailImage] = React.useState(null);
+
+ React.useEffect(() => {
+ let isMounted = true,
+ uriToDispose;
+ setThumbnailImage(null);
+
+ (async () => {
+ if (thumbnailURI) {
+ await preloadImage(thumbnailURI);
+ if (isMounted) {
+ setThumbnailImage(thumbnailURI);
+ }
+ return;
+ }
+
+ invariant(
+ thumbnailHolder && thumbnailEncryptionKey,
+ 'invalid encrypted thumbnail source',
+ );
+ const { result } = await decryptMedia(
+ thumbnailHolder,
+ thumbnailEncryptionKey,
+ );
+ if (isMounted && result.success) {
+ setThumbnailImage(result.uri);
+ uriToDispose = result.uri;
+ }
+ })();
+
+ return () => {
+ isMounted = false;
+ if (uriToDispose) {
+ URL.revokeObjectURL(uriToDispose);
+ }
+ };
+ }, [thumbnailURI, thumbnailHolder, thumbnailEncryptionKey]);
+
+ let videoSource;
+ if (uri) {
+ videoSource = <source src={uri} />;
+ }
+ const poster = thumbnailImage ?? thumbHashDataURL;
+ return (
+ <video controls poster={poster} style={elementStyle} ref={videoRef}>
+ {videoSource}
+ </video>
+ );
+}
+
+const MemoizedLoadableVideo: React.AbstractComponent<Props, HTMLVideoElement> =
+ React.memo<Props, HTMLVideoElement>(
+ React.forwardRef<Props, HTMLVideoElement>(LoadableVideo),
+ );
+
+export default MemoizedLoadableVideo;

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 16, 1:18 AM (10 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5941130
Default Alt Text
D7946.1768526320.diff (2 KB)

Event Timeline