Make lightbox use the same cache
This commit is contained in:
@@ -12,8 +12,8 @@ import Animated, {
|
||||
} from 'react-native-reanimated'
|
||||
import {Image} from 'expo-image'
|
||||
|
||||
import {useImageDimensions} from '#/lib/media/image-sizes'
|
||||
import type {Dimensions as ImageDimensions, ImageSource} from '../../@types'
|
||||
import useImageDimensions from '../../hooks/useImageDimensions'
|
||||
import {
|
||||
applyRounding,
|
||||
createTransform,
|
||||
@@ -52,7 +52,10 @@ const ImageItem = ({
|
||||
isScrollViewBeingDragged,
|
||||
}: Props) => {
|
||||
const [isScaled, setIsScaled] = useState(false)
|
||||
const imageDimensions = useImageDimensions(imageSrc)
|
||||
const imageDimensions = useImageDimensions({
|
||||
src: imageSrc.uri,
|
||||
knownDimensions: undefined, // TODO: We have those.
|
||||
})
|
||||
const committedTransform = useSharedValue(initialTransform)
|
||||
const panTranslation = useSharedValue({x: 0, y: 0})
|
||||
const pinchOrigin = useSharedValue({x: 0, y: 0})
|
||||
|
||||
@@ -19,8 +19,8 @@ import Animated, {
|
||||
import {Image} from 'expo-image'
|
||||
|
||||
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
|
||||
import {useImageDimensions} from '#/lib/media/image-sizes'
|
||||
import {Dimensions as ImageDimensions, ImageSource} from '../../@types'
|
||||
import useImageDimensions from '../../hooks/useImageDimensions'
|
||||
|
||||
const SWIPE_CLOSE_OFFSET = 75
|
||||
const SWIPE_CLOSE_VELOCITY = 1
|
||||
@@ -47,7 +47,10 @@ const ImageItem = ({
|
||||
const scrollViewRef = useAnimatedRef<Animated.ScrollView>()
|
||||
const translationY = useSharedValue(0)
|
||||
const [scaled, setScaled] = useState(false)
|
||||
const imageDimensions = useImageDimensions(imageSrc)
|
||||
const imageDimensions = useImageDimensions({
|
||||
src: imageSrc.uri,
|
||||
knownDimensions: undefined, // TODO: We have those.
|
||||
})
|
||||
const maxZoomScale = imageDimensions
|
||||
? (imageDimensions.width / SCREEN.width) * MAX_ORIGINAL_IMAGE_ZOOM
|
||||
: 1
|
||||
@@ -179,7 +182,7 @@ const styles = StyleSheet.create({
|
||||
})
|
||||
|
||||
const getZoomRectAfterDoubleTap = (
|
||||
imageDimensions: ImageDimensions | null,
|
||||
imageDimensions: ImageDimensions | undefined,
|
||||
touchX: number,
|
||||
touchY: number,
|
||||
): {
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* 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 {Dimensions, ImageSource} from '../@types'
|
||||
|
||||
const CACHE_SIZE = 50
|
||||
|
||||
type CacheStorageItem = {key: string; value: any}
|
||||
|
||||
const createCache = (cacheSize: number) => ({
|
||||
_storage: [] as CacheStorageItem[],
|
||||
get(key: string): any {
|
||||
const {value} =
|
||||
this._storage.find(({key: storageKey}) => storageKey === key) || {}
|
||||
|
||||
return value
|
||||
},
|
||||
set(key: string, value: any) {
|
||||
if (this._storage.length >= cacheSize) {
|
||||
this._storage.shift()
|
||||
}
|
||||
|
||||
this._storage.push({key, value})
|
||||
},
|
||||
})
|
||||
|
||||
const imageDimensionsCache = createCache(CACHE_SIZE)
|
||||
|
||||
const useImageDimensions = (image: ImageSource): Dimensions | null => {
|
||||
const [dimensions, setDimensions] = useState<Dimensions | null>(null)
|
||||
|
||||
const getImageDimensions = (
|
||||
image: ImageSource,
|
||||
): Promise<Dimensions | null> => {
|
||||
return new Promise(resolve => {
|
||||
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) => {
|
||||
if (width > 0 && height > 0) {
|
||||
imageDimensionsCache.set(cacheKey, {width, height})
|
||||
resolve({width, height})
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
},
|
||||
() => {
|
||||
resolve(null)
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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