diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js
index 2f2e4f15e3f3..2017962b5e83 100644
--- a/src/components/ImageView/index.js
+++ b/src/components/ImageView/index.js
@@ -7,6 +7,7 @@ import styles from '../../styles/styles';
import * as StyleUtils from '../../styles/StyleUtils';
import canUseTouchScreen from '../../libs/canUseTouchscreen';
import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions';
+import FullscreenLoadingIndicator from '../FullscreenLoadingIndicator';
const propTypes = {
/** URL to full-sized image */
@@ -23,7 +24,10 @@ class ImageView extends PureComponent {
this.onContainerPressIn = this.onContainerPressIn.bind(this);
this.onContainerPress = this.onContainerPress.bind(this);
this.onContainerPressOut = this.onContainerPressOut.bind(this);
+ this.imageLoadingStart = this.imageLoadingStart.bind(this);
+ this.imageLoadingEnd = this.imageLoadingEnd.bind(this);
this.state = {
+ isLoading: false,
containerHeight: 0,
containerWidth: 0,
isZoomed: false,
@@ -227,6 +231,14 @@ class ImageView extends PureComponent {
this.setState(prevState => ({isDragging: prevState.isMouseDown}));
}
+ imageLoadingStart() {
+ this.setState({isLoading: true});
+ }
+
+ imageLoadingEnd() {
+ this.setState({isLoading: false});
+ }
+
render() {
if (this.canUseTouchScreen) {
return (
@@ -240,7 +252,14 @@ class ImageView extends PureComponent {
styles.h100,
]}
resizeMode="contain"
+ onLoadStart={this.imageLoadingStart}
+ onLoadEnd={this.imageLoadingEnd}
/>
+ {this.state.isLoading && (
+
+ )}
);
}
@@ -274,8 +293,16 @@ class ImageView extends PureComponent {
styles.w100,
]}
resizeMode="contain"
+ onLoadStart={this.imageLoadingStart}
+ onLoadEnd={this.imageLoadingEnd}
/>
+
+ {this.state.isLoading && (
+
+ )}
);
}
diff --git a/src/components/ImageView/index.native.js b/src/components/ImageView/index.native.js
index 58e5ac905f9d..360210ac50f9 100644
--- a/src/components/ImageView/index.native.js
+++ b/src/components/ImageView/index.native.js
@@ -1,6 +1,8 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
-import {View, InteractionManager, PanResponder} from 'react-native';
+import {
+ View, InteractionManager, PanResponder,
+} from 'react-native';
import Image from 'react-native-fast-image';
import ImageZoom from 'react-native-image-pan-zoom';
import ImageSize from 'react-native-image-size';
@@ -9,6 +11,7 @@ import styles from '../../styles/styles';
import * as StyleUtils from '../../styles/StyleUtils';
import variables from '../../styles/variables';
import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions';
+import FullscreenLoadingIndicator from '../FullscreenLoadingIndicator';
/**
* On the native layer, we use a image library to handle zoom functionality
@@ -25,6 +28,7 @@ class ImageView extends PureComponent {
super(props);
this.state = {
+ isLoading: false,
thumbnailWidth: 100,
thumbnailHeight: 100,
imageWidth: undefined,
@@ -43,6 +47,9 @@ class ImageView extends PureComponent {
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: this.updatePanResponderTouches.bind(this),
});
+
+ this.imageLoadingStart = this.imageLoadingStart.bind(this);
+ this.imageLoadingEnd = this.imageLoadingEnd.bind(this);
}
componentDidMount() {
@@ -100,6 +107,14 @@ class ImageView extends PureComponent {
return false;
}
+ imageLoadingStart() {
+ this.setState({isLoading: true});
+ }
+
+ imageLoadingEnd() {
+ this.setState({isLoading: false});
+ }
+
render() {
// Default windowHeight accounts for the modal header height
const windowHeight = this.props.windowHeight - variables.contentHeaderHeight;
@@ -120,7 +135,10 @@ class ImageView extends PureComponent {
+
);
@@ -177,7 +195,9 @@ class ImageView extends PureComponent {
this.props.style,
]}
source={{uri: this.props.url}}
- resizeMode={Image.resizeMode.contain}
+ resizeMode="contain"
+ onLoadStart={this.imageLoadingStart}
+ onLoadEnd={this.imageLoadingEnd}
/>
{/**
Create an invisible view on top of the image so we can capture and set the amount of touches before
@@ -194,6 +214,11 @@ class ImageView extends PureComponent {
]}
/>
+ {this.state.isLoading && (
+
+ )}
);
}
diff --git a/src/components/ImageWithSizeCalculation.js b/src/components/ImageWithSizeCalculation.js
index 698da27c610e..3b6eee240d11 100644
--- a/src/components/ImageWithSizeCalculation.js
+++ b/src/components/ImageWithSizeCalculation.js
@@ -1,9 +1,10 @@
import React, {PureComponent} from 'react';
-import {Image} from 'react-native';
+import {View, Image} from 'react-native';
import PropTypes from 'prop-types';
import Log from '../libs/Log';
import styles from '../styles/styles';
import makeCancellablePromise from '../libs/MakeCancellablePromise';
+import FullscreenLoadingIndicator from './FullscreenLoadingIndicator';
const propTypes = {
/** Url for image to display */
@@ -29,6 +30,17 @@ const defaultProps = {
* it can be appropriately resized.
*/
class ImageWithSizeCalculation extends PureComponent {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ isLoading: false,
+ };
+
+ this.imageLoadingStart = this.imageLoadingStart.bind(this);
+ this.imageLoadingEnd = this.imageLoadingEnd.bind(this);
+ }
+
componentDidMount() {
this.calculateImageSize();
}
@@ -83,17 +95,39 @@ class ImageWithSizeCalculation extends PureComponent {
});
}
+ imageLoadingStart() {
+ this.setState({isLoading: true});
+ }
+
+ imageLoadingEnd() {
+ this.setState({isLoading: false});
+ }
+
render() {
return (
-
+ >
+
+ {this.state.isLoading && (
+
+ )}
+
);
}
}
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 9eab8076ae71..6ba66e585eae 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -317,6 +317,10 @@ const styles = {
backgroundColor: 'transparent',
},
+ opacity1: {
+ opacity: 1,
+ },
+
textDanger: {
color: colors.red,
},