Skip to content

Instantly share code, notes, and snippets.

@janicduplessis
Created November 28, 2019 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janicduplessis/b04a207e2778c3ca5e40f646c7a2dcf0 to your computer and use it in GitHub Desktop.
Save janicduplessis/b04a207e2778c3ca5e40f646c7a2dcf0 to your computer and use it in GitHub Desktop.
import * as React from 'react';
import { Image, View, StyleSheet, ViewStyle, ImageProps } from 'react-native';
type ImageURISource = Readonly<{
uri?: string | undefined;
}>;
type Props = {
style?: ViewStyle | null | undefined;
lowResSource: ImageURISource;
hiResSource: ImageURISource;
fadeDuration?: number;
resizeMode?: ImageProps['resizeMode'];
};
type State = {
hiResLoaded: boolean;
};
export default class ProgressiveImage extends React.Component<Props, State> {
static _loadedImages = new Set();
state = {
hiResLoaded: ProgressiveImage._loadedImages.has(this.props.hiResSource.uri),
};
_timeout: any;
componentWillUnmount() {
clearTimeout(this._timeout);
}
_onHighResLoad = () => {
if (this.state.hiResLoaded) {
return;
}
ProgressiveImage._loadedImages.add(this.props.hiResSource.uri);
this._timeout = setTimeout(
() => this.setState({ hiResLoaded: true }),
this.props.fadeDuration != null ? this.props.fadeDuration : 300,
);
};
render() {
const { lowResSource, hiResSource, style, ...others } = this.props;
return (
<View style={style}>
{!this.state.hiResLoaded && (
<Image
{...others}
style={StyleSheet.absoluteFill}
source={lowResSource}
/>
)}
<Image
{...others}
onLoad={this._onHighResLoad}
style={StyleSheet.absoluteFill}
source={hiResSource}
/>
</View>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment