Skip to content

Instantly share code, notes, and snippets.

@sturmenta
Created October 11, 2022 08:33
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 sturmenta/f5e83ba9a50fcb8c3d1a945ff66944d9 to your computer and use it in GitHub Desktop.
Save sturmenta/f5e83ba9a50fcb8c3d1a945ff66944d9 to your computer and use it in GitHub Desktop.
react-native uri-image with progress indicator
import React, {useState} from 'react';
import {ImageProps, View} from 'react-native';
import FastImage, {FastImageProps} from 'react-native-fast-image';
import {useComponentTrackTrace} from '_hooks';
import {ShowProgress} from '_atoms';
import {ToastShow} from '_utils';
import {getNewImageSizeByAspectRatio} from './get-new-image-size-by-aspect-ratio';
import {FastImageSource} from 'types/fast-image';
interface ScalableImageUriCommonProps {
source: FastImageSource;
style?: ImageProps['style'];
placeholderSpinnerBoxSize?: number;
imageProps?: FastImageProps;
}
type ScalableImageUriProps = ScalableImageUriCommonProps &
({width: number; height?: number} | {width?: number; height: number});
export const ScalableImageUri: React.FC<ScalableImageUriProps> = ({
source,
style,
width,
height,
placeholderSpinnerBoxSize = 200,
imageProps,
}: ScalableImageUriProps) => {
useComponentTrackTrace('Component_ScalableImageUri');
const [loading, setLoading] = useState(false);
const [progress, setProgress] = useState<number>(1);
const [imageSize, setImageSize] = useState<{
width: number;
height: number;
}>();
return (
<>
<FastImage
{...imageProps}
source={source as FastImageSource}
style={{
...(style ? (style as object) : {}),
...imageSize,
position: loading ? 'absolute' : 'relative',
}}
onLoadStart={() => setLoading(true)}
onProgress={e =>
setProgress(e.nativeEvent.loaded / e.nativeEvent.total)
}
onLoad={e => {
setImageSize(
getNewImageSizeByAspectRatio({
widthReadFromImage: e.nativeEvent.width,
heightReadFromImage: e.nativeEvent.height,
...(width ? {desiredWidth: width!} : {desiredHeight: height!}),
}),
);
}}
onLoadEnd={() => setLoading(false)}
onError={() => {
ToastShow({
type: 'error',
text: 'Hubo un error al cargar la imagen',
});
}}
/>
{loading ? (
<View
style={{
height: placeholderSpinnerBoxSize,
alignItems: 'center',
justifyContent: 'center',
}}>
<ShowProgress progress={progress} />
</View>
) : null}
</>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment