import * as React from "react"; import { ImageStyle, View } from "react-native"; import * as R from "ramda"; import { QBImage } from "@applicaster/zapp-react-native-ui-components/Components/Image"; import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils"; import { useImageSourceWithDefault, useCheckFailedUri } from "./hooks"; import useImageSize from "./hooks/useImageSize"; type Source = { uri: string; }; type Props = Record & { style: ImageStyle; uri?: string; placeholderImage?: string; entry?: ZappEntry | ZappFeed; withDimensions: (source: Source) => Source; }; const MemoizedImage = React.memo(QBImage, R.equals); const isValidExternalSource = (source): boolean => source?.uri?.startsWith("http") || source?.uri?.startsWith("data:image") || source?.uri?.startsWith("file://"); export default function Image({ style, uri, placeholderImage, entry, withDimensions, ...otherProps }: Props) { const [showDefault, setShowDefault] = React.useState(false); const { appendFailedToLoadUri, isFailedToLoadUri } = useCheckFailedUri(); // TODO: RE-implement this feature so it applies red overlay on too big images, instead of logging. // runOnceCheckTooBigImageSize( // uri, // toFiniteNumberWithDefault(0, style.width), // toFiniteNumberWithDefault(0, style.height) // ); const source = useImageSourceWithDefault({ uri, entry, showDefault, placeholderImage: placeholderImage || "", otherProps, }); const onError = React.useCallback(() => { appendFailedToLoadUri(uri); setShowDefault(true); }, []); const fallback = React.useMemo( () => showDefault || !isValidExternalSource(source), [source?.uri, showDefault] ); const applyMaxSize = toBooleanWithDefaultFalse(otherProps?.applyMaxSize); const sourceWithMaxSizes = useImageSize({ style, applyMaxSize, source, withDimensions, }); if (isFailedToLoadUri(uri) || !isValidExternalSource(source)) { return ; } return ( ); }