import React, { useState, memo, forwardRef, useCallback, useRef } from 'react';
import { Image as RNImage } from 'react-native';
import Text from '../Text';
import { usePropsResolution } from '../../../hooks/useThemeProps';
import type { IImageProps } from './types';
import { useHasResponsiveProps } from '../../../hooks/useHasResponsiveProps';
import { makeStyledComponent } from '../../../utils/styled';
const StyledImage = makeStyledComponent(RNImage);
const Image = memo(
forwardRef((props: IImageProps, ref: any) => {
const {
source,
src,
fallbackElement,
alt,
fallbackSource,
ignoreFallback,
_alt,
...resolvedProps
} = usePropsResolution('Image', props);
const finalSource: any = useRef(null);
const getSource = useCallback(() => {
if (source) {
finalSource.current = source;
} else if (src) {
finalSource.current = { uri: src };
}
return finalSource.current;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [source?.uri, src]);
const [renderedSource, setSource] = useState(getSource());
const [alternate, setAlternate] = useState(false);
const [fallbackSourceFlag, setfallbackSourceFlag] = useState(true);
React.useEffect(() => {
setSource(getSource());
return () => {
finalSource.current = null;
};
}, [source?.uri, src, getSource]);
const onImageLoadError = useCallback(
(event: any) => {
props.onError && props.onError(event);
console.warn(event.nativeEvent.error);
if (
!ignoreFallback &&
fallbackSource &&
fallbackSource !== renderedSource &&
fallbackSourceFlag
) {
setfallbackSourceFlag(false);
setSource(fallbackSource);
} else {
setAlternate(true);
}
},
[
fallbackSource,
fallbackSourceFlag,
ignoreFallback,
props,
renderedSource,
]
);
//TODO: refactor for responsive prop
if (useHasResponsiveProps(props)) {
return null;
}
if (typeof alt !== 'string') {
console.warn('Please pass alt prop to Image component');
}
if (alternate) {
if (fallbackElement) {
if (React.isValidElement(fallbackElement)) {
return fallbackElement;
}
} else return {alt};
}
return (
);
})
);
interface ImageStatics {
getSize: typeof RNImage.prefetch;
prefetch: typeof RNImage.prefetch;
queryCache: typeof RNImage.queryCache;
}
const ImageWithStatics: typeof Image & ImageStatics = {
...Image,
//@ts-ignore
getSize: RNImage.getSize,
prefetch: RNImage.prefetch,
queryCache: RNImage.queryCache,
};
export default ImageWithStatics;
export type { IImageProps };