diff options
author | Aryan Goharzad <arrygoo@gmail.com> | 2023-01-25 18:25:34 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-25 17:25:34 -0600 |
commit | eb33c3fa812cc087db14a6b6ba743e982b26c462 (patch) | |
tree | d098f7a804c67755f39e95bbbfd56887bacf476c /src/view/com/lightbox/ImageViewing/hooks/useImageDimensions.ts | |
parent | adf328b50ce98c5ebd3282fe897ddfdcd0de8011 (diff) | |
download | voidsky-eb33c3fa812cc087db14a6b6ba743e982b26c462.tar.zst |
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
Diffstat (limited to 'src/view/com/lightbox/ImageViewing/hooks/useImageDimensions.ts')
-rw-r--r-- | src/view/com/lightbox/ImageViewing/hooks/useImageDimensions.ts | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/view/com/lightbox/ImageViewing/hooks/useImageDimensions.ts b/src/view/com/lightbox/ImageViewing/hooks/useImageDimensions.ts new file mode 100644 index 000000000..bab136c50 --- /dev/null +++ b/src/view/com/lightbox/ImageViewing/hooks/useImageDimensions.ts @@ -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 |