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
|
/**
* Copyright (c) JOB TODAY S.A. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import {useEffect, useState} from 'react'
import {Image, ImageURISource} from 'react-native'
import {createCache} from '../utils'
import {Dimensions, ImageSource} from '../@types'
const CACHE_SIZE = 50
const imageDimensionsCache = createCache(CACHE_SIZE)
const useImageDimensions = (image: ImageSource): Dimensions | null => {
const [dimensions, setDimensions] = useState<Dimensions | null>(null)
// eslint-disable-next-line @typescript-eslint/no-shadow
const getImageDimensions = (image: ImageSource): Promise<Dimensions> => {
return new Promise(resolve => {
if (typeof image === 'number') {
const cacheKey = `${image}`
let imageDimensions = imageDimensionsCache.get(cacheKey)
if (!imageDimensions) {
const {width, height} = Image.resolveAssetSource(image)
imageDimensions = {width, height}
imageDimensionsCache.set(cacheKey, imageDimensions)
}
resolve(imageDimensions)
return
}
// @ts-ignore
if (image.uri) {
const source = image as ImageURISource
const cacheKey = source.uri as string
const imageDimensions = imageDimensionsCache.get(cacheKey)
if (imageDimensions) {
resolve(imageDimensions)
} else {
Image.getSizeWithHeaders(
// @ts-ignore
source.uri,
source.headers,
(width: number, height: number) => {
imageDimensionsCache.set(cacheKey, {width, height})
resolve({width, height})
},
() => {
resolve({width: 0, height: 0})
},
)
}
} else {
resolve({width: 0, height: 0})
}
})
}
let isImageUnmounted = false
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-shadow
getImageDimensions(image).then(dimensions => {
if (!isImageUnmounted) {
setDimensions(dimensions)
}
})
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
isImageUnmounted = true
}
}, [image])
return dimensions
}
export default useImageDimensions
|