An ATproto social media client -- with an independent Appview.
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix animations and gestures getting reset on state updates in the lightbox (#1618)

* Fix translation resetting on state update

* Copy getImageStyles into iOS and Android forks

* Fix opacity resetting on state update

authored by

dan and committed by
GitHub
4ec5fabd 260b03a0

+57 -42
+24 -1
src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx
··· 22 22 import useImageDimensions from '../../hooks/useImageDimensions' 23 23 import usePanResponder from '../../hooks/usePanResponder' 24 24 25 - import {getImageStyles, getImageTransform} from '../../utils' 25 + import {getImageTransform} from '../../utils' 26 26 import {ImageSource} from '../../@types' 27 27 import {ImageLoading} from './ImageLoading' 28 28 ··· 132 132 height: SCREEN_HEIGHT * 2, 133 133 }, 134 134 }) 135 + 136 + const getImageStyles = ( 137 + image: {width: number; height: number} | null, 138 + translate: Animated.ValueXY, 139 + scale?: Animated.Value, 140 + ) => { 141 + if (!image?.width || !image?.height) { 142 + return {width: 0, height: 0} 143 + } 144 + 145 + const transform = translate.getTranslateTransform() 146 + 147 + if (scale) { 148 + // @ts-ignore TODO - is scale incorrect? might need to remove -prf 149 + transform.push({scale}, {perspective: new Animated.Value(1000)}) 150 + } 151 + 152 + return { 153 + width: image.width, 154 + height: image.height, 155 + transform, 156 + } 157 + } 135 158 136 159 export default React.memo(ImageItem)
+27 -12
src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx
··· 23 23 24 24 import useImageDimensions from '../../hooks/useImageDimensions' 25 25 26 - import {getImageStyles, getImageTransform} from '../../utils' 26 + import {getImageTransform} from '../../utils' 27 27 import {ImageSource} from '../../@types' 28 28 import {ImageLoading} from './ImageLoading' 29 29 ··· 52 52 const [scaled, setScaled] = useState(false) 53 53 const imageDimensions = useImageDimensions(imageSrc) 54 54 const [translate, scale] = getImageTransform(imageDimensions, SCREEN) 55 - 56 - // TODO: It's not valid to reinitialize Animated values during render. 57 - // This is a bug. 58 - const scrollValueY = new Animated.Value(0) 59 - const scaleValue = new Animated.Value(scale || 1) 60 - const translateValue = new Animated.ValueXY(translate) 55 + const [scrollValueY] = useState(() => new Animated.Value(0)) 61 56 const maxScrollViewZoom = MAX_SCALE / (scale || 1) 62 57 63 58 const imageOpacity = scrollValueY.interpolate({ 64 59 inputRange: [-SWIPE_CLOSE_OFFSET, 0, SWIPE_CLOSE_OFFSET], 65 60 outputRange: [0.5, 1, 0.5], 66 61 }) 67 - const imagesStyles = getImageStyles( 68 - imageDimensions, 69 - translateValue, 70 - scaleValue, 71 - ) 62 + const imagesStyles = getImageStyles(imageDimensions, translate, scale || 1) 72 63 const imageStylesWithOpacity = {...imagesStyles, opacity: imageOpacity} 73 64 74 65 const onScrollEndDrag = useCallback( ··· 257 248 y: rectY, 258 249 height: rectHeight, 259 250 width: rectWidth, 251 + } 252 + } 253 + 254 + const getImageStyles = ( 255 + image: {width: number; height: number} | null, 256 + translate: {readonly x: number; readonly y: number} | undefined, 257 + scale?: number, 258 + ) => { 259 + if (!image?.width || !image?.height) { 260 + return {width: 0, height: 0} 261 + } 262 + const transform = [] 263 + if (translate) { 264 + transform.push({translateX: translate.x}) 265 + transform.push({translateY: translate.y}) 266 + } 267 + if (scale) { 268 + // @ts-ignore TODO - is scale incorrect? might need to remove -prf 269 + transform.push({scale}, {perspective: new Animated.Value(1000)}) 270 + } 271 + return { 272 + width: image.width, 273 + height: image.height, 274 + transform, 260 275 } 261 276 } 262 277
+6 -5
src/view/com/lightbox/ImageViewing/index.tsx
··· 69 69 const imageList = useRef<VirtualizedList<ImageSource>>(null) 70 70 const [opacity, setOpacity] = useState(1) 71 71 const [currentImageIndex, setImageIndex] = useState(imageIndex) 72 - 73 - // TODO: It's not valid to reinitialize Animated values during render. 74 - // This is a bug. 75 - const headerTranslate = new Animated.ValueXY(INITIAL_POSITION) 76 - const footerTranslate = new Animated.ValueXY(INITIAL_POSITION) 72 + const [headerTranslate] = useState( 73 + () => new Animated.ValueXY(INITIAL_POSITION), 74 + ) 75 + const [footerTranslate] = useState( 76 + () => new Animated.ValueXY(INITIAL_POSITION), 77 + ) 77 78 78 79 const toggleBarsVisible = (isVisible: boolean) => { 79 80 if (isVisible) {
-24
src/view/com/lightbox/ImageViewing/utils.ts
··· 6 6 * 7 7 */ 8 8 9 - import {Animated} from 'react-native' 10 9 import {Dimensions, Position} from './@types' 11 10 12 11 export const getImageTransform = ( ··· 23 22 const {x, y} = getImageTranslate(image, screen) 24 23 25 24 return [{x, y}, scale] as const 26 - } 27 - 28 - export const getImageStyles = ( 29 - image: Dimensions | null, 30 - translate: Animated.ValueXY, 31 - scale?: Animated.Value, 32 - ) => { 33 - if (!image?.width || !image?.height) { 34 - return {width: 0, height: 0} 35 - } 36 - 37 - const transform = translate.getTranslateTransform() 38 - 39 - if (scale) { 40 - // @ts-ignore TODO - is scale incorrect? might need to remove -prf 41 - transform.push({scale}, {perspective: new Animated.Value(1000)}) 42 - } 43 - 44 - return { 45 - width: image.width, 46 - height: image.height, 47 - transform, 48 - } 49 25 } 50 26 51 27 export const getImageTranslate = (