import React, {useCallback, useEffect, useState} from 'react' import { Image, ImageStyle, TouchableOpacity, TouchableWithoutFeedback, StyleSheet, View, Pressable, ViewStyle, } from 'react-native' import { FontAwesomeIcon, FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' import {colors, s} from 'lib/styles' import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader' import {Text} from '../util/text/Text' import {useLingui} from '@lingui/react' import {msg} from '@lingui/macro' import { useLightbox, useLightboxControls, ImagesLightbox, ProfileImageLightbox, } from '#/state/lightbox' import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' interface Img { uri: string alt?: string } export function Lightbox() { const {activeLightbox} = useLightbox() const {closeLightbox} = useLightboxControls() const isActive = !!activeLightbox useWebBodyScrollLock(isActive) if (!isActive) { return null } const initialIndex = activeLightbox instanceof ImagesLightbox ? activeLightbox.index : 0 let imgs: Img[] | undefined if (activeLightbox instanceof ProfileImageLightbox) { const opts = activeLightbox if (opts.profile.avatar) { imgs = [{uri: opts.profile.avatar}] } } else if (activeLightbox instanceof ImagesLightbox) { const opts = activeLightbox imgs = opts.images } if (!imgs) { return null } return ( ) } function LightboxInner({ imgs, initialIndex = 0, onClose, }: { imgs: Img[] initialIndex: number onClose: () => void }) { const {_} = useLingui() const [index, setIndex] = useState(initialIndex) const [isAltExpanded, setAltExpanded] = useState(false) const canGoLeft = index >= 1 const canGoRight = index < imgs.length - 1 const onPressLeft = useCallback(() => { if (canGoLeft) { setIndex(index - 1) } }, [index, canGoLeft]) const onPressRight = useCallback(() => { if (canGoRight) { setIndex(index + 1) } }, [index, canGoRight]) const onKeyDown = useCallback( (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose() } else if (e.key === 'ArrowLeft') { onPressLeft() } else if (e.key === 'ArrowRight') { onPressRight() } }, [onClose, onPressLeft, onPressRight], ) useEffect(() => { window.addEventListener('keydown', onKeyDown) return () => window.removeEventListener('keydown', onKeyDown) }, [onKeyDown]) const {isTabletOrDesktop} = useWebMediaQueries() const btnStyle = React.useMemo(() => { return isTabletOrDesktop ? styles.btnTablet : styles.btnMobile }, [isTabletOrDesktop]) const iconSize = React.useMemo(() => { return isTabletOrDesktop ? 32 : 24 }, [isTabletOrDesktop]) return ( {canGoLeft && ( )} {canGoRight && ( )} {imgs[index].alt ? ( { setAltExpanded(!isAltExpanded) }}> {imgs[index].alt} ) : null} ) } const styles = StyleSheet.create({ mask: { // @ts-ignore position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: '#000c', }, imageCenterer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, image: { width: '100%', height: '100%', resizeMode: 'contain', }, icon: { color: colors.white, }, closeBtn: { position: 'absolute', top: 10, right: 10, }, btn: { position: 'absolute', backgroundColor: '#00000077', justifyContent: 'center', alignItems: 'center', }, btnTablet: { width: 50, height: 50, borderRadius: 25, left: 30, right: 30, }, btnMobile: { width: 44, height: 44, borderRadius: 22, left: 20, right: 20, }, leftBtn: { right: 'auto', top: '50%', }, rightBtn: { left: 'auto', top: '50%', }, footer: { paddingHorizontal: 32, paddingVertical: 24, backgroundColor: colors.black, }, blurredBackground: { backdropFilter: 'blur(10px)', WebkitBackdropFilter: 'blur(10px)', } as ViewStyle, })