UNPKG

@elacity-js/uikit

Version:

React / Material UI Design kit for Elacity project

105 lines (102 loc) 3.93 kB
import { __rest } from '../node_modules/tslib/tslib.es6.js'; import { jsx } from 'react/jsx-runtime'; import React__default from 'react'; import { Fade } from '@mui/material'; import { toIpfsGateway, retry } from '@elacity-js/lib'; import useMounted from '../hooks/useMounted.js'; // eslint-disable-next-line max-len const loadImageAsync = (src, img) => () => new Promise((resolve, reject) => { const imgEl = new Image(); const $el = img || imgEl; const handleLoad = () => { resolve($el); }; const handleError = () => { $el.removeEventListener('load', handleLoad); $el.removeEventListener('error', handleError); reject(new Error('failed to load image, attempts exhausted')); }; $el.addEventListener('load', handleLoad); $el.addEventListener('error', handleError); if (!img) { imgEl.src = src; } }); const useImageGracefullyLoad = (src, o) => { const mounted = useMounted(); const [source, setSrc] = React__default.useState(o.disabled ? toIpfsGateway(src) : o.fallbackImage || toIpfsGateway(src)); const [hasError, setHasError] = React__default.useState(false); const [isLoading, setLoading] = React__default.useState(!o.disabled); const handleError = (hasErr) => { if (mounted.current) { setHasError(hasErr); } }; const handleLoading = (value) => { if (mounted.current) { setLoading(value); } }; const handleSrc = (value) => { if (mounted.current) { setSrc(value); } }; const ref = React__default.useRef(null); React__default.useEffect(() => { const trustedSrc = toIpfsGateway(src); if (o.disabled) { handleLoading(false); handleSrc(trustedSrc); } else if (trustedSrc.match(/^http/)) { handleLoading(true); retry(loadImageAsync(trustedSrc, ref.current), { interval: o.retryInterval || 500, retries: o.retries || 10, backoffFactor: o.backoffFactor, }) .then(() => { handleSrc(trustedSrc); handleError(false); }) .catch(() => { console.warn(`failed to load ${trustedSrc}, exhausted all attempts`); handleSrc(o.errorImage || o.fallbackImage); handleError(true); }) .finally(() => handleLoading(false)); } else if (src === '' || src === null || typeof src === 'undefined') { handleSrc(o.errorImage || o.fallbackImage); handleError(true); handleLoading(false); } else { handleSrc(trustedSrc); } }, [src]); return { source, hasError, isLoading, ref, disabled: o.disabled || false, }; }; const ImageComponent = (_a) => { var { src, style, retries, retryInterval, backoffFactor, processing } = _a, props = __rest(_a, ["src", "style", "retries", "retryInterval", "backoffFactor", "processing"]); const { source, hasError, isLoading, ref } = useImageGracefullyLoad(src, { retries: retries || 10, retryInterval: retryInterval || 500, backoffFactor, }); return (jsx(Fade, Object.assign({ in: !hasError && !isLoading }, { children: jsx("img", Object.assign({ ref: ref }, props, { style: Object.assign(Object.assign(Object.assign(Object.assign({}, style), { transition: 'all 1s ease-out' }), (hasError && { filter: 'blur(4px) grayscale(0.7) opacity(0.5)', })), ((isLoading || processing) && { animation: 'pulse 2s infinite', filter: 'opacity(0.8) grayscale(0.7)', })), src: source })) }))); }; export { ImageComponent as default, useImageGracefullyLoad }; //# sourceMappingURL=Image.js.map