Saves image on long press (#83)
* Saves image on long press * Adds save on long press * Forking lightbox * move to wrapper only to the bottom sheet to reduce impact of this change * lint * lint * lint * Use official `share` API * Clean up cache after download * comment * comment * Reduce swipe close velocity * Updates per feedback * lint * bugfix * Adds delayed press-in for TouchableOpacity
This commit is contained in:
@@ -0,0 +1,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 {
|
||||
// @ts-ignore
|
||||
Image.getSizeWithHeaders(
|
||||
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
|
||||
Reference in New Issue
Block a user