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:
// 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 {SystemBars} from 'react-native-edge-to-edge'
import {Gesture} from 'react-native-gesture-handler'
@@ -105,7 +105,7 @@ export default function ImageViewRoot({
setActiveLightbox(nextLightbox)
}
React.useEffect(() => {
useEffect(() => {
if (!nextLightbox) {
return
}
@@ -140,10 +140,10 @@ export default function ImageViewRoot({
const onOpenProgressChange = useCallback((isOpen: boolean) => {
setIsCompletelyOpen(isOpen)
if (isOpen) {
ScreenOrientation.unlockAsync()
void ScreenOrientation.unlockAsync()
} else {
// 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'
openProgress.set(0)
runOnJS(onRequestClose)()
@@ -227,7 +227,7 @@ function ImageView({
const [isDragging, setIsDragging] = useState(false)
const [imageIndex, setImageIndex] = useState(initialImageIndex)
const [showControls, setShowControls] = useState(true)
const [isAltExpanded, setAltExpanded] = React.useState(false)
const [isAltExpanded, setAltExpanded] = useState(false)
const dismissSwipeTranslateY = useSharedValue(0)
const isFlyingAway = useSharedValue(false)
@@ -381,25 +381,27 @@ function ImageView({
</View>
))}
</PagerView>
<View style={styles.controls}>
<Animated.View
style={animatedHeaderStyle}
renderToHardwareTextureAndroid>
<ImageDefaultHeader onRequestClose={onRequestClose} />
</Animated.View>
<Animated.View
style={animatedFooterStyle}
renderToHardwareTextureAndroid={!isAltExpanded}>
<LightboxFooter
images={images}
index={imageIndex}
isAltExpanded={isAltExpanded}
toggleAltExpanded={() => setAltExpanded(e => !e)}
onPressSave={onPressSave}
onPressShare={onPressShare}
/>
</Animated.View>
</View>
{isCompletelyOpen && (
<View style={styles.controls}>
<Animated.View
style={animatedHeaderStyle}
renderToHardwareTextureAndroid>
<ImageDefaultHeader onRequestClose={onRequestClose} />
</Animated.View>
<Animated.View
style={animatedFooterStyle}
renderToHardwareTextureAndroid={!isAltExpanded}>
<LightboxFooter
images={images}
index={imageIndex}
isAltExpanded={isAltExpanded}
toggleAltExpanded={() => setAltExpanded(e => !e)}
onPressSave={onPressSave}
onPressShare={onPressShare}
/>
</Animated.View>
</View>
)}
</Animated.View>
)
}
@@ -431,7 +433,7 @@ function LightboxImage({
openProgress: 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
let imageAspect: number | undefined
if (dims) {
@@ -443,7 +445,7 @@ function LightboxImage({
const safeFrameDelayedForJSThreadOnly = useSafeAreaFrame()
const safeInsetsDelayedForJSThreadOnly = useSafeAreaInsets()
const measureSafeArea = React.useCallback(() => {
const measureSafeArea = useCallback(() => {
'worklet'
let safeArea: Rect | null = measure(safeAreaRef)
if (!safeArea) {
@@ -580,7 +582,7 @@ function LightboxFooter({
onPressShare: (uri: string) => void
}) {
const {alt: altText, uri} = images[index]
const isMomentumScrolling = React.useRef(false)
const isMomentumScrolling = useRef(false)
return (
<ScrollView
style={styles.footerScrollView}