diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx index 27ffece7ad..40df4c8199 100644 --- a/src/view/com/lightbox/ImageViewing/index.tsx +++ b/src/view/com/lightbox/ImageViewing/index.tsx @@ -9,12 +9,26 @@ // https://github.com/jobtoday/react-native-image-viewing import React, {useCallback, useMemo, useState} from 'react' -import {Platform, StyleSheet, View} from 'react-native' +import { + Dimensions, + LayoutAnimation, + Platform, + StyleSheet, + View, +} from 'react-native' import PagerView from 'react-native-pager-view' import {MeasuredDimensions} from 'react-native-reanimated' import Animated, {useAnimatedStyle, withSpring} from 'react-native-reanimated' +import {useSafeAreaInsets} from 'react-native-safe-area-context' import {Edge, SafeAreaView} from 'react-native-safe-area-context' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {Trans} from '@lingui/macro' +import {colors, s} from '#/lib/styles' +import {isIOS} from '#/platform/detection' +import {Button} from '#/view/com/util/forms/Button' +import {Text} from '#/view/com/util/text/Text' +import {ScrollView} from '#/view/com/util/Views' import {ImageSource} from './@types' import ImageDefaultHeader from './components/ImageDefaultHeader' import ImageItem from './components/ImageItem/ImageItem' @@ -26,9 +40,11 @@ type Props = { visible: boolean onRequestClose: () => void backgroundColor?: string - renderFooter: (index: number) => React.ReactNode + onPressSave: (uri: string) => void + onPressShare: (uri: string) => void } +const SCREEN_HEIGHT = Dimensions.get('window').height const DEFAULT_BG_COLOR = '#000' function ImageViewing({ @@ -38,7 +54,8 @@ function ImageViewing({ visible, onRequestClose, backgroundColor = DEFAULT_BG_COLOR, - renderFooter, + onPressSave, + onPressShare, }: Props) { const [isScaled, setIsScaled] = useState(false) const [isDragging, setIsDragging] = useState(false) @@ -122,13 +139,99 @@ function ImageViewing({ ))} - {renderFooter(imageIndex)} + ) } +function LightboxFooter({ + images, + index, + onPressSave, + onPressShare, +}: { + images: ImageSource[] + index: number + onPressSave: (uri: string) => void + onPressShare: (uri: string) => void +}) { + const {alt: altText, uri} = images[index] + const [isAltExpanded, setAltExpanded] = React.useState(false) + const insets = useSafeAreaInsets() + const svMaxHeight = SCREEN_HEIGHT - insets.top - 50 + const isMomentumScrolling = React.useRef(false) + return ( + { + isMomentumScrolling.current = true + }} + onMomentumScrollEnd={() => { + isMomentumScrolling.current = false + }} + contentContainerStyle={{ + paddingTop: 16, + paddingBottom: insets.bottom + 10, + paddingHorizontal: 24, + }}> + {altText ? ( + + { + if (isMomentumScrolling.current) { + return + } + LayoutAnimation.configureNext({ + duration: 450, + update: {type: 'spring', springDamping: 1}, + }) + setAltExpanded(prev => !prev) + }} + onLongPress={() => {}}> + {altText} + + + ) : null} + + + + + + ) +} + const styles = StyleSheet.create({ screen: { position: 'absolute', @@ -157,6 +260,21 @@ const styles = StyleSheet.create({ zIndex: 1, bottom: 0, }, + footerText: { + paddingBottom: isIOS ? 20 : 16, + }, + footerBtns: { + flexDirection: 'row', + justifyContent: 'center', + gap: 8, + }, + footerBtn: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + backgroundColor: 'transparent', + borderColor: colors.white, + }, }) const EnhancedImageViewing = (props: Props) => ( diff --git a/src/view/com/lightbox/Lightbox.tsx b/src/view/com/lightbox/Lightbox.tsx index 5bce025946..ed570d5a79 100644 --- a/src/view/com/lightbox/Lightbox.tsx +++ b/src/view/com/lightbox/Lightbox.tsx @@ -1,24 +1,13 @@ import React from 'react' -import {Dimensions, LayoutAnimation, StyleSheet, View} from 'react-native' -import {useSafeAreaInsets} from 'react-native-safe-area-context' import * as MediaLibrary from 'expo-media-library' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {msg, Trans} from '@lingui/macro' +import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {saveImageToMediaLibrary, shareImageModal} from '#/lib/media/manip' -import {colors, s} from '#/lib/styles' -import {isIOS} from '#/platform/detection' import {useLightbox, useLightboxControls} from '#/state/lightbox' -import {ImageSource} from '#/view/com/lightbox/ImageViewing/@types' -import {ScrollView} from '#/view/com/util/Views' -import {Button} from '../util/forms/Button' -import {Text} from '../util/text/Text' import * as Toast from '../util/Toast' import ImageView from './ImageViewing' -const SCREEN_HEIGHT = Dimensions.get('window').height - export function Lightbox() { const {activeLightbox} = useLightbox() const {closeLightbox} = useLightboxControls() @@ -71,110 +60,8 @@ export function Lightbox() { thumbDims={activeLightbox.thumbDims} visible onRequestClose={onClose} - renderFooter={index => ( - - )} + onPressSave={saveImageToAlbumWithToasts} + onPressShare={uri => shareImageModal({uri})} /> ) } - -function LightboxFooter({ - images, - index, - onPressSave, -}: { - images: ImageSource[] - index: number - onPressSave: (uri: string) => void -}) { - const {alt: altText, uri} = images[index] - const [isAltExpanded, setAltExpanded] = React.useState(false) - const insets = useSafeAreaInsets() - const svMaxHeight = SCREEN_HEIGHT - insets.top - 50 - const isMomentumScrolling = React.useRef(false) - return ( - { - isMomentumScrolling.current = true - }} - onMomentumScrollEnd={() => { - isMomentumScrolling.current = false - }} - contentContainerStyle={{ - paddingTop: 16, - paddingBottom: insets.bottom + 10, - paddingHorizontal: 24, - }}> - {altText ? ( - - { - if (isMomentumScrolling.current) { - return - } - LayoutAnimation.configureNext({ - duration: 450, - update: {type: 'spring', springDamping: 1}, - }) - setAltExpanded(prev => !prev) - }} - onLongPress={() => {}}> - {altText} - - - ) : null} - - - - - - ) -} - -const styles = StyleSheet.create({ - footerText: { - paddingBottom: isIOS ? 20 : 16, - }, - footerBtns: { - flexDirection: 'row', - justifyContent: 'center', - gap: 8, - }, - footerBtn: { - flexDirection: 'row', - alignItems: 'center', - gap: 8, - backgroundColor: 'transparent', - borderColor: colors.white, - }, -})