Page MenuHomePhabricator

D7765.id26312.diff
No OneTemporary

D7765.id26312.diff

diff --git a/native/media/encrypted-image.react.js b/native/media/encrypted-image.react.js
--- a/native/media/encrypted-image.react.js
+++ b/native/media/encrypted-image.react.js
@@ -4,7 +4,7 @@
import { MediaCacheContext } from 'lib/components/media-cache-provider.react.js';
-import { decryptMedia } from './encryption-utils.js';
+import { decryptBase64, decryptMedia } from './encryption-utils.js';
import LoadableImage from './loadable-image.react.js';
import { useSelector } from '../redux/redux-utils.js';
import type { ImageStyle } from '../types/styles.js';
@@ -16,13 +16,14 @@
+spinnerColor: string,
+style: ImageStyle,
+invisibleLoad: boolean,
+ +thumbHash?: ?string,
};
type Props = {
...BaseProps,
};
function EncryptedImage(props: Props): React.Node {
- const { holder, encryptionKey, onLoad: onLoadProp } = props;
+ const { holder, encryptionKey, onLoad: onLoadProp, thumbHash } = props;
const mediaCache = React.useContext(MediaCacheContext);
const [source, setSource] = React.useState(null);
@@ -38,6 +39,18 @@
prevConnectionStatusRef.current = connectionStatus;
}
+ const placeholder = React.useMemo(() => {
+ if (!thumbHash) {
+ return null;
+ }
+ try {
+ const thumbhash = decryptBase64(thumbHash, encryptionKey);
+ return { thumbhash };
+ } catch (e) {
+ return null;
+ }
+ }, [thumbHash, encryptionKey]);
+
React.useEffect(() => {
let isMounted = true;
setSource(null);
@@ -74,6 +87,7 @@
return (
<LoadableImage
+ placeholder={placeholder}
source={source}
onLoad={onLoad}
spinnerColor={spinnerColor}
diff --git a/native/media/loadable-image.react.js b/native/media/loadable-image.react.js
--- a/native/media/loadable-image.react.js
+++ b/native/media/loadable-image.react.js
@@ -8,6 +8,7 @@
import type { ImageStyle } from '../types/styles.js';
type Props = {
+ +placeholder: ?ImageSource,
+source: ?ImageSource,
+onLoad: () => void,
+spinnerColor: string,
@@ -15,7 +16,7 @@
+invisibleLoad: boolean,
};
function LoadableImage(props: Props): React.Node {
- const { source, onLoad: onLoadProp } = props;
+ const { source, placeholder, onLoad: onLoadProp } = props;
const [loaded, setLoaded] = React.useState(false);
@@ -30,7 +31,14 @@
);
if (!loaded && props.invisibleLoad) {
- return <Image source={source} onLoad={onLoad} style={invisibleStyle} />;
+ return (
+ <Image
+ source={source}
+ placeholder={placeholder}
+ onLoad={onLoad}
+ style={invisibleStyle}
+ />
+ );
}
let spinner;
@@ -44,8 +52,13 @@
return (
<View style={styles.container}>
+ <Image
+ source={source}
+ placeholder={placeholder}
+ onLoad={onLoad}
+ style={props.style}
+ />
{spinner}
- <Image source={source} onLoad={onLoad} style={props.style} />
</View>
);
}
diff --git a/native/media/multimedia.react.js b/native/media/multimedia.react.js
--- a/native/media/multimedia.react.js
+++ b/native/media/multimedia.react.js
@@ -16,11 +16,13 @@
| {
+kind: 'uri',
+uri: string,
+ +thumbHash?: ?string,
}
| {
+kind: 'encrypted',
+holder: string,
+encryptionKey: string,
+ +thumbHash?: ?string,
};
type BaseProps = {
+mediaInfo: MediaInfo | AvatarMediaInfo,
@@ -111,6 +113,7 @@
if (source.kind === 'encrypted') {
return (
<EncryptedImage
+ thumbHash={source.thumbHash}
holder={source.holder}
encryptionKey={source.encryptionKey}
onLoad={this.onLoad}
@@ -121,12 +124,14 @@
/>
);
}
- const { uri } = source;
+ const { uri, thumbHash } = source;
+ const placeholder = thumbHash ? { thumbhash: thumbHash } : null;
if (uri.startsWith('http')) {
return (
<RemoteImage
uri={uri}
onLoad={this.onLoad}
+ placeholder={placeholder}
spinnerColor={this.props.spinnerColor}
style={styles.image}
invisibleLoad={invisibleLoad}
@@ -138,6 +143,7 @@
<Image
source={{ uri }}
onLoad={this.onLoad}
+ placeholder={placeholder}
style={styles.image}
key={uri}
/>
diff --git a/native/media/remote-image.react.js b/native/media/remote-image.react.js
--- a/native/media/remote-image.react.js
+++ b/native/media/remote-image.react.js
@@ -1,6 +1,7 @@
// @flow
import * as React from 'react';
+import type { ImageSource } from 'react-native/Libraries/Image/ImageSource';
import { type ConnectionStatus } from 'lib/types/socket-types.js';
@@ -14,6 +15,7 @@
+spinnerColor: string,
+style: ImageStyle,
+invisibleLoad: boolean,
+ +placeholder?: ?ImageSource,
};
type Props = {
...BaseProps,
@@ -41,12 +43,13 @@
}
render() {
- const { style, spinnerColor, invisibleLoad, uri } = this.props;
+ const { style, spinnerColor, invisibleLoad, uri, placeholder } = this.props;
const source = { uri };
return (
<LoadableImage
source={source}
+ placeholder={placeholder}
onLoad={this.onLoad}
spinnerColor={spinnerColor}
style={style}

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 3, 5:20 AM (21 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2610381
Default Alt Text
D7765.id26312.diff (5 KB)

Event Timeline