File size: 4,321 Bytes
cdc95a6
947c08e
 
cffd4ca
947c08e
 
 
 
 
 
 
 
 
cdc95a6
 
947c08e
 
 
 
 
 
 
 
4af0f6c
cdc95a6
947c08e
cdc95a6
 
947c08e
cdc95a6
 
947c08e
 
cdc95a6
947c08e
 
 
 
cdc95a6
 
947c08e
cdc95a6
 
947c08e
cdc95a6
 
947c08e
 
cdc95a6
947c08e
 
 
cdc95a6
 
947c08e
 
 
 
 
 
 
 
 
0ab8c90
947c08e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cdc95a6
947c08e
 
 
cd23862
947c08e
cdc95a6
947c08e
 
 
0ab8c90
cd23862
 
 
 
 
0ab8c90
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
109
110
111
112
113
114
115
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,"image/png")}
                    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 () => {
            imageData.current = null
            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={()=>{
                            if (onLoad) onLoad();
                        }}
                        onLoadEnd={()=>{
                            if (onLoad) onLoadEnd();
                            imageData.current = null;
                        }}
                    />
                    : <View style={{...style,display:'flex',justifyContent:"center",alignItems:"center"}}>
                        <ActivityIndicator animating={true}/>
                    </View>
                }</>
            }
            
        </>  
    )
}

export default Image