File size: 4,043 Bytes
cdc95a6
947c08e
 
cffd4ca
947c08e
 
 
 
 
 
 
 
 
cdc95a6
 
947c08e
 
 
 
 
 
 
 
cdc95a6
 
947c08e
cdc95a6
 
947c08e
cdc95a6
 
947c08e
 
cdc95a6
947c08e
 
 
 
cdc95a6
 
947c08e
cdc95a6
 
947c08e
cdc95a6
 
947c08e
 
cdc95a6
947c08e
 
 
cdc95a6
 
947c08e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cdc95a6
947c08e
 
 
 
cdc95a6
947c08e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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