also defer control rendering

This commit is contained in:
Samuel Newman
2026-01-26 14:39:49 +02:00
parent 4b34a9eb06
commit 85fb3b8df0
+30 -28
View File
@@ -8,7 +8,7 @@
// Original code copied and simplified from the link below as the codebase is currently not maintained: // Original code copied and simplified from the link below as the codebase is currently not maintained:
// https://github.com/jobtoday/react-native-image-viewing // https://github.com/jobtoday/react-native-image-viewing
import React, {useCallback, useEffect, useMemo, useState} from 'react' import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {LayoutAnimation, PixelRatio, StyleSheet, View} from 'react-native' import {LayoutAnimation, PixelRatio, StyleSheet, View} from 'react-native'
import {SystemBars} from 'react-native-edge-to-edge' import {SystemBars} from 'react-native-edge-to-edge'
import {Gesture} from 'react-native-gesture-handler' import {Gesture} from 'react-native-gesture-handler'
@@ -105,7 +105,7 @@ export default function ImageViewRoot({
setActiveLightbox(nextLightbox) setActiveLightbox(nextLightbox)
} }
React.useEffect(() => { useEffect(() => {
if (!nextLightbox) { if (!nextLightbox) {
return return
} }
@@ -140,10 +140,10 @@ export default function ImageViewRoot({
const onOpenProgressChange = useCallback((isOpen: boolean) => { const onOpenProgressChange = useCallback((isOpen: boolean) => {
setIsCompletelyOpen(isOpen) setIsCompletelyOpen(isOpen)
if (isOpen) { if (isOpen) {
ScreenOrientation.unlockAsync() void ScreenOrientation.unlockAsync()
} else { } else {
// default is PORTRAIT_UP - set via config plugin in app.config.js -sfn // default is PORTRAIT_UP - set via config plugin in app.config.js -sfn
ScreenOrientation.lockAsync(PORTRAIT_UP) void ScreenOrientation.lockAsync(PORTRAIT_UP)
} }
}, []) }, [])
@@ -158,7 +158,7 @@ export default function ImageViewRoot({
}, },
) )
const onFlyAway = React.useCallback(() => { const onFlyAway = useCallback(() => {
'worklet' 'worklet'
openProgress.set(0) openProgress.set(0)
runOnJS(onRequestClose)() runOnJS(onRequestClose)()
@@ -227,7 +227,7 @@ function ImageView({
const [isDragging, setIsDragging] = useState(false) const [isDragging, setIsDragging] = useState(false)
const [imageIndex, setImageIndex] = useState(initialImageIndex) const [imageIndex, setImageIndex] = useState(initialImageIndex)
const [showControls, setShowControls] = useState(true) const [showControls, setShowControls] = useState(true)
const [isAltExpanded, setAltExpanded] = React.useState(false) const [isAltExpanded, setAltExpanded] = useState(false)
const dismissSwipeTranslateY = useSharedValue(0) const dismissSwipeTranslateY = useSharedValue(0)
const isFlyingAway = useSharedValue(false) const isFlyingAway = useSharedValue(false)
@@ -381,25 +381,27 @@ function ImageView({
</View> </View>
))} ))}
</PagerView> </PagerView>
<View style={styles.controls}> {isCompletelyOpen && (
<Animated.View <View style={styles.controls}>
style={animatedHeaderStyle} <Animated.View
renderToHardwareTextureAndroid> style={animatedHeaderStyle}
<ImageDefaultHeader onRequestClose={onRequestClose} /> renderToHardwareTextureAndroid>
</Animated.View> <ImageDefaultHeader onRequestClose={onRequestClose} />
<Animated.View </Animated.View>
style={animatedFooterStyle} <Animated.View
renderToHardwareTextureAndroid={!isAltExpanded}> style={animatedFooterStyle}
<LightboxFooter renderToHardwareTextureAndroid={!isAltExpanded}>
images={images} <LightboxFooter
index={imageIndex} images={images}
isAltExpanded={isAltExpanded} index={imageIndex}
toggleAltExpanded={() => setAltExpanded(e => !e)} isAltExpanded={isAltExpanded}
onPressSave={onPressSave} toggleAltExpanded={() => setAltExpanded(e => !e)}
onPressShare={onPressShare} onPressSave={onPressSave}
/> onPressShare={onPressShare}
</Animated.View> />
</View> </Animated.View>
</View>
)}
</Animated.View> </Animated.View>
) )
} }
@@ -431,7 +433,7 @@ function LightboxImage({
openProgress: SharedValue<number> openProgress: SharedValue<number>
dismissSwipeTranslateY: SharedValue<number> dismissSwipeTranslateY: SharedValue<number>
}) { }) {
const [fetchedDims, setFetchedDims] = React.useState<Dimensions | null>(null) const [fetchedDims, setFetchedDims] = useState<Dimensions | null>(null)
const dims = fetchedDims ?? imageSrc.dimensions ?? imageSrc.thumbDimensions const dims = fetchedDims ?? imageSrc.dimensions ?? imageSrc.thumbDimensions
let imageAspect: number | undefined let imageAspect: number | undefined
if (dims) { if (dims) {
@@ -443,7 +445,7 @@ function LightboxImage({
const safeFrameDelayedForJSThreadOnly = useSafeAreaFrame() const safeFrameDelayedForJSThreadOnly = useSafeAreaFrame()
const safeInsetsDelayedForJSThreadOnly = useSafeAreaInsets() const safeInsetsDelayedForJSThreadOnly = useSafeAreaInsets()
const measureSafeArea = React.useCallback(() => { const measureSafeArea = useCallback(() => {
'worklet' 'worklet'
let safeArea: Rect | null = measure(safeAreaRef) let safeArea: Rect | null = measure(safeAreaRef)
if (!safeArea) { if (!safeArea) {
@@ -580,7 +582,7 @@ function LightboxFooter({
onPressShare: (uri: string) => void onPressShare: (uri: string) => void
}) { }) {
const {alt: altText, uri} = images[index] const {alt: altText, uri} = images[index]
const isMomentumScrolling = React.useRef(false) const isMomentumScrolling = useRef(false)
return ( return (
<ScrollView <ScrollView
style={styles.footerScrollView} style={styles.footerScrollView}