|
import { useState, useEffect, useContext, useCallback, useRef } from "react" |
|
import { Image as _Image } from 'expo-image'; |
|
import { View } from "react-native" |
|
import ImageCacheStorage from "@/constants/module/storages/image_cache_storage"; |
|
import {blobToBase64} from "@/constants/module/file_manager"; |
|
import { Icon, Button } from 'react-native-paper'; |
|
import { ActivityIndicator } from 'react-native-paper'; |
|
import { CONTEXT } from "@/constants/module/context"; |
|
import { useFocusEffect } from "expo-router"; |
|
|
|
|
|
|
|
const Image = ({source, style, onError, contentFit, transition, onLoad, onLoadEnd}:any) => { |
|
const [imageLoaded, setImageLoaded]:any = useState(false) |
|
const imageData:any = useRef(null) |
|
const [isError, setIsError]:any = useState(false) |
|
const {showCloudflareTurnstileContext, setShowCloudflareTurnstileContext}:any = useContext(CONTEXT) |
|
const controller = new AbortController(); |
|
const signal = controller.signal; |
|
const request_image = () =>{ |
|
(async ()=>{ |
|
if(source.hasOwnProperty("type")){ |
|
if (source.type === "blob"){ |
|
imageData.current = {uri:await blobToBase64(source.data)} |
|
setImageLoaded(true) |
|
}else if (source.type === "base64"){ |
|
imageData.current = {uri:source.data} |
|
setImageLoaded(true) |
|
}else if (source.type === "file_path"){ |
|
imageData.current = {uri:source.data} |
|
setImageLoaded(true) |
|
}else{ |
|
setIsError(true) |
|
setImageLoaded(false) |
|
} |
|
} else if (source.hasOwnProperty("uri")){ |
|
const result:any = await ImageCacheStorage.get(setShowCloudflareTurnstileContext,source.uri,signal); |
|
if (result.type === "blob"){ |
|
imageData.current = {uri:await blobToBase64(result.data)} |
|
setImageLoaded(true) |
|
}else if (result.type === "base64"){ |
|
imageData.current = {uri:result.data} |
|
setImageLoaded(true) |
|
}else if (result.type === "file_path"){ |
|
imageData.current = {uri:result.data} |
|
setImageLoaded(true) |
|
}else{ |
|
setIsError(true) |
|
setImageLoaded(false) |
|
} |
|
|
|
}else{ |
|
imageData.current = source |
|
setImageLoaded(true) |
|
} |
|
|
|
|
|
})() |
|
|
|
} |
|
|
|
useFocusEffect(useCallback(() => { |
|
return () => { |
|
controller.abort(); |
|
}; |
|
},[])) |
|
|
|
useEffect(()=>{ |
|
request_image() |
|
},[]) |
|
|
|
return ( <> |
|
{isError |
|
? <View style={{...style,display:'flex',justifyContent:"center",alignItems:"center"}}> |
|
<Button mode="outlined" onPress={()=>{ |
|
request_image() |
|
setIsError(false) |
|
}} |
|
style={{ |
|
borderWidth:0, |
|
}} |
|
> |
|
<Icon source={"refresh-circle"} size={25} color={"yellow"}/> |
|
</Button> |
|
</View> |
|
: <>{imageLoaded |
|
|
|
|
|
? <_Image |
|
onError={onError} |
|
source={imageData.current} |
|
style={style} |
|
contentFit={contentFit} |
|
transition={transition} |
|
onLoad={onLoad} |
|
onLoadEnd={onLoadEnd} |
|
/> |
|
: <View style={{...style,display:'flex',justifyContent:"center",alignItems:"center"}}> |
|
<ActivityIndicator animating={true}/> |
|
</View> |
|
}</> |
|
} |
|
|
|
</> |
|
) |
|
} |
|
|
|
export default Image |