-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
handle unlimited requested api call and add fallbackIcon props #29560
Changes from 2 commits
26b59ea
704c4d9
b0ffb2c
f2db0de
4a5d8d3
0c1ec7a
c1d3a83
e74ca7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,20 @@ | ||
import _ from 'underscore'; | ||
import React, {useState, useRef, useEffect} from 'react'; | ||
import React, {useState, useEffect, useMemo} from 'react'; | ||
import {View} from 'react-native'; | ||
import PropTypes from 'prop-types'; | ||
import Log from '../libs/Log'; | ||
import styles from '../styles/styles'; | ||
import FullscreenLoadingIndicator from './FullscreenLoadingIndicator'; | ||
import Image from './Image'; | ||
import useNetwork from '../hooks/useNetwork'; | ||
|
||
// Define constants for load states | ||
const LoadState = { | ||
INITIAL: 'initial', | ||
LOADING: 'loading', | ||
LOADED: 'loaded', | ||
ERRORED: 'errored', | ||
}; | ||
|
||
const propTypes = { | ||
/** Url for image to display */ | ||
|
@@ -39,16 +48,18 @@ const defaultProps = { | |
* | ||
*/ | ||
function ImageWithSizeCalculation(props) { | ||
const isLoadedRef = useRef(null); | ||
const [loadState, setLoadState] = useState(LoadState.INITIAL); | ||
const [isImageCached, setIsImageCached] = useState(true); | ||
const [isLoading, setIsLoading] = useState(false); | ||
|
||
const source = useMemo(() => ({ uri: props.url }), [props.url]); | ||
const {isOffline} = useNetwork(); | ||
|
||
const onError = () => { | ||
Log.hmmm('Unable to fetch image to calculate size', {url: props.url}); | ||
setLoadState(LoadState.ERRORED); | ||
}; | ||
|
||
const imageLoadedSuccessfully = (event) => { | ||
isLoadedRef.current = true; | ||
setLoadState(LoadState.LOADED); | ||
props.onMeasure({ | ||
width: event.nativeEvent.width, | ||
height: event.nativeEvent.height, | ||
|
@@ -57,39 +68,41 @@ function ImageWithSizeCalculation(props) { | |
|
||
/** Delay the loader to detect whether the image is being loaded from the cache or the internet. */ | ||
useEffect(() => { | ||
if (isLoadedRef.current || !isLoading) { | ||
if (loadState !== LoadState.LOADING) { | ||
return; | ||
} | ||
const timeout = _.delay(() => { | ||
if (!isLoading || isLoadedRef.current) { | ||
if (loadState !== LoadState.LOADING) { | ||
return; | ||
} | ||
setLoadState(LoadState.ERRORED); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove this line, this delay is just to indicate whether the current image is fetched from the internet or cache, it does not mean the loading failed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is done. |
||
setIsImageCached(false); | ||
}, 200); | ||
return () => clearTimeout(timeout); | ||
}, [isLoading]); | ||
}, [loadState]); | ||
|
||
return ( | ||
<View style={[styles.w100, styles.h100, props.style]}> | ||
<Image | ||
style={[styles.w100, styles.h100]} | ||
source={{uri: props.url}} | ||
source={source} | ||
isAuthTokenRequired={props.isAuthTokenRequired} | ||
resizeMode={Image.resizeMode.cover} | ||
onLoadStart={() => { | ||
if (isLoadedRef.current || isLoading) { | ||
return; | ||
if (loadState === LoadState.LOADED || isOffline) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need to execute There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is done. |
||
setLoadState(LoadState.INITIAL); | ||
} else { | ||
setLoadState(LoadState.LOADING); | ||
} | ||
setIsLoading(true); | ||
}} | ||
onLoadEnd={() => { | ||
setIsLoading(false); | ||
setLoadState(LoadState.LOADED); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we just need to execute this in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is done. |
||
setIsImageCached(true); | ||
}} | ||
onError={onError} | ||
onLoad={imageLoadedSuccessfully} | ||
/> | ||
{isLoading && !isImageCached && <FullscreenLoadingIndicator style={[styles.opacity1, styles.bgTransparent]} />} | ||
{loadState === LoadState.LOADING && !isImageCached && <FullscreenLoadingIndicator style={[styles.opacity1, styles.bgTransparent]} />} | ||
</View> | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can replace this line with
useNetwork({onReconnect: () => setLoadState(LoadState.LOADING)})
;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain which we need to change because if we change only,
const {isOffline} = useNetwork();
this line then it is okay but I don't understand why we need to replace this line,
const source = useMemo(() => ({ uri: props.url }), [props.url]);
it is being used for displaying image
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, my mistake, I meant just replacing this line
const {isOffline} = useNetwork();
😅