xref: /expo/packages/expo-image/build/web/hooks.js (revision cf6af4e9)
1import { useEffect, useMemo, useState } from 'react';
2import { useBlurhash } from '../utils/blurhash/useBlurhash';
3import { isThumbhashString } from '../utils/resolveSources';
4import { thumbHashStringToDataURL } from '../utils/thumbhash/thumbhash';
5export function useThumbhash(source) {
6    const isThumbhash = isThumbhashString(source?.uri || '');
7    const strippedThumbhashString = source?.uri?.replace(/thumbhash:\//, '') ?? '';
8    const thumbhashSource = useMemo(() => (isThumbhash ? { uri: thumbHashStringToDataURL(strippedThumbhashString) } : null), [strippedThumbhashString, isThumbhash]);
9    return thumbhashSource;
10}
11export function useImageHashes(source) {
12    const thumbhash = useThumbhash(source);
13    const blurhash = useBlurhash(source);
14    return useMemo(() => ({
15        resolvedSource: blurhash ?? thumbhash ?? source,
16        isImageHash: !!blurhash || !!thumbhash,
17    }), [blurhash, thumbhash]);
18}
19export function useHeaders(source, cachePolicy, onError) {
20    const [objectURL, setObjectURL] = useState(null);
21    useEffect(() => {
22        (async () => {
23            if (!source?.headers || !source.uri) {
24                return;
25            }
26            try {
27                const result = await fetch(source.uri, {
28                    headers: source.headers,
29                    cache: cachePolicy === 'none' ? 'no-cache' : 'default',
30                    redirect: 'follow',
31                });
32                if (!result.ok) {
33                    throw new Error(`Failed to fetch image: ${result.status} ${result.statusText}`);
34                }
35                const blob = await result.blob();
36                setObjectURL((prevObjURL) => {
37                    if (prevObjURL) {
38                        URL.revokeObjectURL(prevObjURL);
39                    }
40                    return URL.createObjectURL(blob);
41                });
42                // eslint-disable-next-line @typescript-eslint/no-unused-vars
43            }
44            catch (error) {
45                onError?.forEach((e) => e?.({ source }));
46            }
47        })();
48    }, [source]);
49    if (!source?.headers) {
50        return source;
51    }
52    if (!objectURL) {
53        // Avoid fetching a URL without headers if we have headers
54        return null;
55    }
56    return { ...source, uri: objectURL };
57}
58//# sourceMappingURL=hooks.js.map