diff --git a/native/media/loadable-image.react.js b/native/media/loadable-image.react.js
new file mode 100644
--- /dev/null
+++ b/native/media/loadable-image.react.js
@@ -0,0 +1,69 @@
+// @flow
+
+import { Image } from 'expo-image';
+import * as React from 'react';
+import { View, StyleSheet, ActivityIndicator } from 'react-native';
+import type { ImageSource } from 'react-native/Libraries/Image/ImageSource';
+
+import type { ImageStyle } from '../types/styles.js';
+
+type Props = {
+ +source: ?ImageSource,
+ +onLoad: () => void,
+ +spinnerColor: string,
+ +style: ImageStyle,
+ +invisibleLoad: boolean,
+};
+function LoadableImage(props: Props): React.Node {
+ const { source, onLoad: onLoadProp } = props;
+
+ const [loaded, setLoaded] = React.useState(false);
+
+ const onLoad = React.useCallback(() => {
+ setLoaded(true);
+ onLoadProp && onLoadProp();
+ }, [onLoadProp]);
+
+ if (source && loaded) {
+ return ;
+ }
+
+ if (props.invisibleLoad) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ invisible: {
+ opacity: 0,
+ },
+ spinnerContainer: {
+ alignItems: 'center',
+ bottom: 0,
+ justifyContent: 'center',
+ left: 0,
+ position: 'absolute',
+ right: 0,
+ top: 0,
+ },
+});
+
+export default LoadableImage;
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,11 +1,10 @@
// @flow
-import { Image } from 'expo-image';
import * as React from 'react';
-import { View, StyleSheet, ActivityIndicator } from 'react-native';
import { type ConnectionStatus } from 'lib/types/socket-types.js';
+import LoadableImage from './loadable-image.react.js';
import { useSelector } from '../redux/redux-utils.js';
import type { ImageStyle } from '../types/styles.js';
@@ -46,41 +45,18 @@
}
render() {
- const source = { uri: this.props.uri };
- if (this.state.loaded) {
- return (
-
- );
- }
-
- if (this.props.invisibleLoad) {
- return (
-
- );
- }
+ const { style, spinnerColor, invisibleLoad, uri } = this.props;
+ const source = { uri };
return (
-
-
-
-
-
-
+
);
}
@@ -89,24 +65,6 @@
};
}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- invisible: {
- opacity: 0,
- },
- spinnerContainer: {
- alignItems: 'center',
- bottom: 0,
- justifyContent: 'center',
- left: 0,
- position: 'absolute',
- right: 0,
- top: 0,
- },
-});
-
const ConnectedRemoteImage: React.ComponentType =
React.memo(function ConnectedRemoteImage(props: BaseProps) {
const connectionStatus = useSelector(state => state.connection.status);