UNPKG

react-native-fast-image

Version:
299 lines (298 loc) • 11.2 kB
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); //#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion let react = require("react"); react = __toESM(react); let react_native = require("react-native"); //#region src/constants.ts const resizeMode = { contain: "contain", cover: "cover", stretch: "stretch", center: "center", repeat: "repeat" }; const priority = { low: "low", normal: "normal", high: "high" }; const cacheControl = { immutable: "immutable", web: "web", cacheOnly: "cacheOnly" }; //#endregion //#region src/index.tsx const resolveDefaultSource = (defaultSource) => { if (!defaultSource) return null; if (react_native.Platform.OS === "android") { const resolved = react_native.Image.resolveAssetSource(defaultSource); if (resolved) return resolved.uri; return null; } return defaultSource; }; function tintColorFromStyle(style) { if (Array.isArray(style)) { for (let i = style.length - 1; i >= 0; i--) { const found = tintColorFromStyle(style[i]); if (found !== void 0) return found; } return; } if (typeof style === "number") { const flattened = react_native.StyleSheet.flatten(style); return flattened ? flattened.tintColor : void 0; } return style && typeof style === "object" ? style.tintColor : void 0; } function loopCount(loop) { if (loop === void 0) return -1; if (loop === true) return 0; if (loop === false) return 1; return Number.isFinite(loop) ? Math.max(1, Math.floor(loop)) : 0; } function loadResult(event) { var _event$width, _event$height, _event$error; return event.ok ? { ok: true, width: (_event$width = event.width) !== null && _event$width !== void 0 ? _event$width : 0, height: (_event$height = event.height) !== null && _event$height !== void 0 ? _event$height : 0 } : { ok: false, error: (_event$error = event.error) !== null && _event$error !== void 0 ? _event$error : "Failed to load the image" }; } function withProgress(onProgress) { return onProgress && ((event) => { const { loaded, total } = event.nativeEvent; event.nativeEvent.progress = total > 0 ? Math.min(1, Math.max(0, loaded / total)) : 0; onProgress(event); }); } const DEFAULT_FADE_MS = react_native.Platform.OS === "ios" ? 250 : 300; function transitionProps(transition) { var _transition$duration; const { duration, betweenImages, skipOnCacheHit } = typeof transition === "number" ? { duration: transition } : typeof transition === "object" && transition ? { ...transition, duration: (_transition$duration = transition.duration) !== null && _transition$duration !== void 0 ? _transition$duration : DEFAULT_FADE_MS } : { duration: transition ? DEFAULT_FADE_MS : 0 }; return { transitionDuration: typeof duration === "number" && duration > 0 ? duration : 0, transitionBetweenImages: !!betweenImages, transitionSkipOnCacheHit: skipOnCacheHit || "memory" }; } function withoutCache(source) { const { cache: _cache, ...rest } = source || {}; return rest; } function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, fallback, children, resizeMode = "cover", loop, transition, forwardedRef, onLayout, pointerEvents, hitSlop, onStartShouldSetResponder, onStartShouldSetResponderCapture, onMoveShouldSetResponder, onMoveShouldSetResponderCapture, onResponderGrant, onResponderReject, onResponderStart, onResponderMove, onResponderEnd, onResponderRelease, onResponderTerminationRequest, onResponderTerminate, onTouchStart, onTouchMove, onTouchEnd, onTouchCancel, onTouchEndCapture, ...viewProps }) { const { onClick, ...props } = viewProps; const fallbackResult = (0, react.useRef)(void 0); const wrapperProps = { onLayout, onClick, pointerEvents, hitSlop, onStartShouldSetResponder, onStartShouldSetResponderCapture, onMoveShouldSetResponder, onMoveShouldSetResponderCapture, onResponderGrant, onResponderReject, onResponderStart, onResponderMove, onResponderEnd, onResponderRelease, onResponderTerminationRequest, onResponderTerminate, onTouchStart, onTouchMove, onTouchEnd, onTouchCancel, onTouchEndCapture }; const imageProps = { ...props, pointerEvents: pointerEvents === "box-none" ? "none" : void 0 }; const resolvedTintColor = tintColor != null ? tintColor : tintColorFromStyle(style); if (fallback) { const cleanedSource = typeof source === "number" ? source : Array.isArray(source) ? source.map(withoutCache) : withoutCache(source); const resolvedSource = react_native.Image.resolveAssetSource(cleanedSource); return /* @__PURE__ */ react.default.createElement(react_native.View, { style: [styles.imageContainer, style], ...wrapperProps, ref: forwardedRef }, /* @__PURE__ */ react.default.createElement(react_native.Image, { ...imageProps, style: [styles.fallbackImage, { tintColor: resolvedTintColor }], source: resolvedSource, defaultSource, onLoadStart, onProgress: withProgress(onProgress), onLoad: onLoadEnd ? (event) => { const { width, height } = event.nativeEvent.source; fallbackResult.current = { ok: true, width, height }; onLoad === null || onLoad === void 0 || onLoad(event); } : onLoad, onError: onLoadEnd ? (event) => { fallbackResult.current = { ok: false, error: String(event.nativeEvent.error) }; onError === null || onError === void 0 || onError(event); } : onError, onLoadEnd: onLoadEnd && (() => { var _fallbackResult$curre; return onLoadEnd((_fallbackResult$curre = fallbackResult.current) !== null && _fallbackResult$curre !== void 0 ? _fallbackResult$curre : { ok: false, error: "Failed to load the image" }); }), resizeMode }), children); } const sources = Array.isArray(source) ? source.length === 1 ? void 0 : source : void 0; const single = Array.isArray(source) ? source[0] : source; const resolvedSource = sources ? void 0 : react_native.Image.resolveAssetSource(single); const resolvedDefaultSource = resolveDefaultSource(defaultSource); return /* @__PURE__ */ react.default.createElement(react_native.View, { style: [styles.imageContainer, style], ...wrapperProps, ref: forwardedRef }, /* @__PURE__ */ react.default.createElement(FastImageView, { ...imageProps, tintColor: resolvedTintColor, loopCount: loopCount(loop), ...transitionProps(transition), style: react_native.StyleSheet.absoluteFill, source: resolvedSource, sources, defaultSource: resolvedDefaultSource, onFastImageLoadStart: onLoadStart, onFastImageProgress: withProgress(onProgress), trackProgress: !!onProgress, onFastImageLoad: onLoad, onFastImageError: onError, onFastImageLoadEnd: onLoadEnd && ((event) => onLoadEnd(loadResult(event.nativeEvent))), resizeMode }), children); } const FastImageMemo = (0, react.memo)(FastImageBase); const FastImageComponent = (0, react.forwardRef)((props, ref) => /* @__PURE__ */ react.default.createElement(FastImageMemo, { forwardedRef: ref, ...props })); FastImageComponent.displayName = "FastImage"; const noResult = { ok: false, error: "No result" }; const FastImage = FastImageComponent; FastImage.resizeMode = resizeMode; FastImage.cacheControl = cacheControl; FastImage.priority = priority; const ONE_SOURCE = "Takes one source, not an array of sizes: pass the size to use"; FastImage.preload = (sources) => Promise.resolve(react_native.NativeModules.FastImageView.preload(sources.map((s) => s && !Array.isArray(s) ? s : {}))).then((results) => sources.map((source, i) => { var _results$i; if (Array.isArray(source)) return { ok: false, error: ONE_SOURCE, uri: void 0 }; const uri = source ? source.uri : void 0; const result = (_results$i = results === null || results === void 0 ? void 0 : results[i]) !== null && _results$i !== void 0 ? _results$i : noResult; if (!result.ok) return { ...result, uri }; return typeof uri === "string" ? { ...result, uri } : { ok: false, error: "Invalid source: no uri", uri }; })); FastImage.clearMemoryCache = () => Promise.resolve(react_native.NativeModules.FastImageView.clearMemoryCache()); FastImage.clearDiskCache = () => Promise.resolve(react_native.NativeModules.FastImageView.clearDiskCache()); FastImage.configureCache = (limits = {}) => Promise.resolve(react_native.NativeModules.FastImageView.configureCache(limits)); FastImage.writeToCache = (source, file) => Array.isArray(source) ? Promise.resolve({ ok: false, error: ONE_SOURCE }) : Promise.resolve(react_native.NativeModules.FastImageView.writeToCache(source || {}, file)); FastImage.getCachePath = (source) => Array.isArray(source) ? Promise.resolve({ ok: false, error: ONE_SOURCE }) : Promise.resolve(react_native.NativeModules.FastImageView.getCachePath(source || {})); const styles = react_native.StyleSheet.create({ fallbackImage: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, imageContainer: { overflow: "hidden" } }); /** * An image with content on top of it, like React Native's `ImageBackground`: a * view that the image fills, with the children on top. Use it rather than * giving `FastImage` children, which it won't render in the next major version * (the image will be a single native view). The other props go to the image; * the ref is the view's. */ const FastImageBackground = (0, react.forwardRef)(({ style, imageStyle, imageRef, children, importantForAccessibility, ...props }, ref) => /* @__PURE__ */ react.default.createElement(react_native.View, { accessibilityIgnoresInvertColors: true, importantForAccessibility, style, ref }, /* @__PURE__ */ react.default.createElement(FastImageComponent, { ...props, importantForAccessibility, style: [react_native.StyleSheet.absoluteFill, imageStyle], ref: imageRef }), children)); FastImageBackground.displayName = "FastImageBackground"; const FastImageView = (0, react_native.requireNativeComponent)("FastImageView", FastImage, { nativeOnly: { onFastImageLoadStart: true, onFastImageProgress: true, onFastImageLoad: true, onFastImageError: true, onFastImageLoadEnd: true, trackProgress: true } }); //#endregion exports.FastImageBackground = FastImageBackground; exports.default = FastImage;