import { Image as ExpoImage, type ImageProps as ExpoImageProps } from 'expo-image' import React, { forwardRef, useMemo } from 'react' import { TouchableOpacity, type TouchableOpacityProps } from 'react-native' import tw from 'twrnc' interface ImgProps extends ExpoImageProps { onClick?: () => void touchProps?: TouchableOpacityProps className?: string src?: string | number errorSource?: string | number /** 自定义缓存键,用于需要重定向的 URL */ cacheKey?: string } const Img = forwardRef((props, ref) => { const { onClick, touchProps = {}, className = '', style = {}, src, errorSource, source: propSource, cacheKey, ...reset } = props const imageStyle = tw`${className}` // 判断是否为网络图片 const isNetworkImage = (uri: string | number): boolean => { if (typeof uri !== 'string') return false return uri.startsWith('http://') || uri.startsWith('https://') } // 自动从 URL 提取稳定的缓存键 const extractCacheKey = (url: string): string => { try { const urlObj = new URL(url) // 使用路径部分作为缓存键,忽略查询参数(token、签名等) return urlObj.pathname } catch { // URL 解析失败时使用原始 URL return url } } // 构建图片源 const imageSource = useMemo(() => { // 如果提供了source属性,优先使用 if (propSource) return propSource if (!src) return undefined if (typeof src === 'number') { // 本地图片资源(require导入的资源ID) return src } else { // 网络图片或本地文件路径 if (isNetworkImage(src)) { // 自动提取缓存键:优先使用传入的 cacheKey,否则从 URL 路径自动提取 const autoCacheKey = cacheKey || extractCacheKey(src) return { uri: src, cacheKey: autoCacheKey, } } else { // 本地文件路径 return { uri: src } } } }, [src, propSource, cacheKey]) const imgProps = { style: [style, imageStyle], ref, // placeholder: blurhash, source: imageSource, cachePolicy: 'disk' as const, errorSource, ...reset, } const handlePress = () => { onClick && onClick() } if (onClick) { return ( { // const { cacheType } = event // console.log('缓存类型:', cacheType) // // cacheType 可能的值: // // - 'none' - 没有使用缓存,从网络加载 // // - 'disk' - 从磁盘缓存加载 // // - 'memory' - 从内存缓存加载 // }} /> ) } return }) Img.displayName = 'Img' export default Img