diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-12-24 20:05:54 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-24 20:05:54 +0000 |
commit | 6c9e1d4837e9e385da5ca0c89c28000ad25c70d8 (patch) | |
tree | 8de94bf059fc4065cf228b63f50f23840ceda4d8 /src/view/com/lightbox/ImageViewing | |
parent | f05962a4928e5102e6abe773e938ae8ab941a2c4 (diff) | |
download | voidsky-6c9e1d4837e9e385da5ca0c89c28000ad25c70d8.tar.zst |
Unlock orientation when lightbox is open (#7257)
* unlock orientation when lightbox is open * rm outer safe area view, make sure alt text is safe * restore safe area view for android 14 and below * lock orientation on launch for android * set system ui background to black when lightbox is open * reset state on relayout * catch async functions with noops * rm superfluous catches * Delay unlock until after animation * Simplify how key is determined * Make landscape backdrop opaque --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Diffstat (limited to 'src/view/com/lightbox/ImageViewing')
-rw-r--r-- | src/view/com/lightbox/ImageViewing/index.tsx | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx index 96f78a709..7018d753a 100644 --- a/src/view/com/lightbox/ImageViewing/index.tsx +++ b/src/view/com/lightbox/ImageViewing/index.tsx @@ -40,6 +40,7 @@ import { useSafeAreaFrame, useSafeAreaInsets, } from 'react-native-safe-area-context' +import * as ScreenOrientation from 'expo-screen-orientation' import {StatusBar} from 'expo-status-bar' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {Trans} from '@lingui/macro' @@ -60,11 +61,12 @@ import ImageItem from './components/ImageItem/ImageItem' type Rect = {x: number; y: number; width: number; height: number} +const PORTRAIT_UP = ScreenOrientation.OrientationLock.PORTRAIT_UP const PIXEL_RATIO = PixelRatio.get() const EDGES = Platform.OS === 'android' && Platform.Version < 35 ? (['top', 'bottom', 'left', 'right'] satisfies Edge[]) - : (['left', 'right'] satisfies Edge[]) // iOS or Android 15+, so no top/bottom safe area + : ([] satisfies Edge[]) // iOS or Android 15+ bleeds into safe area const SLOW_SPRING: WithSpringConfig = { mass: isIOS ? 1.25 : 0.75, @@ -102,6 +104,9 @@ export default function ImageViewRoot({ 'use no memo' const ref = useAnimatedRef<View>() const [activeLightbox, setActiveLightbox] = useState(nextLightbox) + const [orientation, setOrientation] = useState<'portrait' | 'landscape'>( + 'portrait', + ) const openProgress = useSharedValue(0) if (!activeLightbox && nextLightbox) { @@ -140,6 +145,20 @@ export default function ImageViewRoot({ }, ) + // Delay the unlock until after we've finished the scale up animation. + // It's complicated to do the same for locking it back so we don't attempt that. + useAnimatedReaction( + () => openProgress.get() === 1, + (isOpen, wasOpen) => { + if (isOpen && !wasOpen) { + runOnJS(ScreenOrientation.unlockAsync)() + } else if (!isOpen && wasOpen) { + // default is PORTRAIT_UP - set via config plugin in app.config.js -sfn + runOnJS(ScreenOrientation.lockAsync)(PORTRAIT_UP) + } + }, + ) + const onFlyAway = React.useCallback(() => { 'worklet' openProgress.set(0) @@ -154,11 +173,21 @@ export default function ImageViewRoot({ aria-modal accessibilityViewIsModal aria-hidden={!activeLightbox}> - <Animated.View ref={ref} style={{flex: 1}} collapsable={false}> + <Animated.View + ref={ref} + style={{flex: 1}} + collapsable={false} + onLayout={e => { + const layout = e.nativeEvent.layout + setOrientation( + layout.height > layout.width ? 'portrait' : 'landscape', + ) + }}> {activeLightbox && ( <ImageView - key={activeLightbox.id} + key={activeLightbox.id + '-' + orientation} lightbox={activeLightbox} + orientation={orientation} onRequestClose={onRequestClose} onPressSave={onPressSave} onPressShare={onPressShare} @@ -174,6 +203,7 @@ export default function ImageViewRoot({ function ImageView({ lightbox, + orientation, onRequestClose, onPressSave, onPressShare, @@ -182,6 +212,7 @@ function ImageView({ openProgress, }: { lightbox: Lightbox + orientation: 'portrait' | 'landscape' onRequestClose: () => void onPressSave: (uri: string) => void onPressShare: (uri: string) => void @@ -221,7 +252,7 @@ function ImageView({ const openProgressValue = openProgress.get() if (openProgressValue < 1) { opacity = Math.sqrt(openProgressValue) - } else if (screenSize) { + } else if (screenSize && orientation === 'portrait') { const dragProgress = Math.min( Math.abs(dismissSwipeTranslateY.get()) / (screenSize.height / 2), 1, |