import { Menu, MenuItem } from '@szhsin/react-menu'; import { getBlurHashAverageColor } from 'fast-blurhash'; import { useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks'; import { useHotkeys } from 'react-hotkeys-hook'; import Icon from './icon'; import Link from './link'; import Media from './media'; import MenuLink from './menu-link'; import Modal from './modal'; import TranslationBlock from './translation-block'; function MediaModal({ mediaAttachments, statusID, instance, index = 0, onClose = () => {}, }) { const carouselRef = useRef(null); const [currentIndex, setCurrentIndex] = useState(index); const carouselFocusItem = useRef(null); useLayoutEffect(() => { carouselFocusItem.current?.scrollIntoView(); history.pushState({ mediaModal: true }, ''); const handlePopState = (e) => { if (e.state?.mediaModal) { onClose(); } }; window.addEventListener('popstate', handlePopState); return () => { window.removeEventListener('popstate', handlePopState); }; }, []); const prevStatusID = useRef(statusID); useEffect(() => { const scrollLeft = index * carouselRef.current.clientWidth; const differentStatusID = prevStatusID.current !== statusID; if (differentStatusID) prevStatusID.current = statusID; carouselRef.current.scrollTo({ left: scrollLeft, behavior: differentStatusID ? 'auto' : 'smooth', }); }, [index, statusID]); const [showControls, setShowControls] = useState(true); useEffect(() => { let handleSwipe = () => { onClose(); }; if (carouselRef.current) { carouselRef.current.addEventListener('swiped-down', handleSwipe); } return () => { if (carouselRef.current) { carouselRef.current.removeEventListener('swiped-down', handleSwipe); } }; }, []); useHotkeys('esc', onClose, [onClose]); const [showMediaAlt, setShowMediaAlt] = useState(false); useEffect(() => { let handleScroll = () => { const { clientWidth, scrollLeft } = carouselRef.current; const index = Math.round(scrollLeft / clientWidth); setCurrentIndex(index); }; if (carouselRef.current) { carouselRef.current.addEventListener('scroll', handleScroll, { passive: true, }); } return () => { if (carouselRef.current) { carouselRef.current.removeEventListener('scroll', handleScroll); } }; }, []); return ( <> {mediaAttachments?.length > 1 && ( )} {!!showMediaAlt && ( { if (e.target === e.currentTarget) { setShowMediaAlt(false); } }} > )} ); } function MediaAltModal({ alt }) { const [forceTranslate, setForceTranslate] = useState(false); return (

Media description

} > { setForceTranslate(true); }} > Translate

{alt}

{forceTranslate && ( )}
); } export default MediaModal;