Skip to content

Commit

Permalink
Merge pull request #8238 from mdneyazahmad/feat/7905-image-loading-in…
Browse files Browse the repository at this point in the history
…dicator

[Feat] Add image loading indicator
  • Loading branch information
mountiny authored Apr 3, 2022
2 parents ce6363c + 773b93f commit 9a8291b
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 8 deletions.
27 changes: 27 additions & 0 deletions src/components/ImageView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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,
Expand Down Expand Up @@ -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 (
Expand All @@ -240,7 +252,14 @@ class ImageView extends PureComponent {
styles.h100,
]}
resizeMode="contain"
onLoadStart={this.imageLoadingStart}
onLoadEnd={this.imageLoadingEnd}
/>
{this.state.isLoading && (
<FullscreenLoadingIndicator
style={[styles.opacity1, styles.bgTransparent]}
/>
)}
</View>
);
}
Expand Down Expand Up @@ -274,8 +293,16 @@ class ImageView extends PureComponent {
styles.w100,
]}
resizeMode="contain"
onLoadStart={this.imageLoadingStart}
onLoadEnd={this.imageLoadingEnd}
/>
</Pressable>

{this.state.isLoading && (
<FullscreenLoadingIndicator
style={[styles.opacity1, styles.bgTransparent]}
/>
)}
</View>
);
}
Expand Down
31 changes: 28 additions & 3 deletions src/components/ImageView/index.native.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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
Expand All @@ -25,6 +28,7 @@ class ImageView extends PureComponent {
super(props);

this.state = {
isLoading: false,
thumbnailWidth: 100,
thumbnailHeight: 100,
imageWidth: undefined,
Expand All @@ -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() {
Expand Down Expand Up @@ -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;
Expand All @@ -120,7 +135,10 @@ class ImageView extends PureComponent {
<Image
source={{uri: this.props.url}}
style={StyleUtils.getWidthAndHeightStyle(this.state.thumbnailWidth, this.state.thumbnailHeight)}
resizeMode={Image.resizeMode.contain}
resizeMode="contain"
/>
<FullscreenLoadingIndicator
style={[styles.opacity1, styles.bgTransparent]}
/>
</View>
);
Expand Down Expand Up @@ -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
Expand All @@ -194,6 +214,11 @@ class ImageView extends PureComponent {
]}
/>
</ImageZoom>
{this.state.isLoading && (
<FullscreenLoadingIndicator
style={[styles.opacity1, styles.bgTransparent]}
/>
)}
</View>
);
}
Expand Down
44 changes: 39 additions & 5 deletions src/components/ImageWithSizeCalculation.js
Original file line number Diff line number Diff line change
@@ -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 */
Expand All @@ -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();
}
Expand Down Expand Up @@ -83,17 +95,39 @@ class ImageWithSizeCalculation extends PureComponent {
});
}

imageLoadingStart() {
this.setState({isLoading: true});
}

imageLoadingEnd() {
this.setState({isLoading: false});
}

render() {
return (
<Image
<View
style={[
styles.w100,
styles.h100,
this.props.style,
]}
source={{uri: this.props.url}}
resizeMode="contain"
/>
>
<Image
style={[
styles.w100,
styles.h100,
]}
source={{uri: this.props.url}}
resizeMode="contain"
onLoadStart={this.imageLoadingStart}
onLoadEnd={this.imageLoadingEnd}
/>
{this.state.isLoading && (
<FullscreenLoadingIndicator
style={[styles.opacity1, styles.bgTransparent]}
/>
)}
</View>
);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ const styles = {
backgroundColor: 'transparent',
},

opacity1: {
opacity: 1,
},

textDanger: {
color: colors.red,
},
Expand Down

0 comments on commit 9a8291b

Please sign in to comment.