import ReactDOM from "react-dom"; import { isMobileOnly, isMobile } from "react-device-detect"; import React, { useRef, useState, useEffect, useCallback } from "react"; import ContextMenu from "@docspace/components/context-menu"; import { StyledViewerContainer } from "../../StyledComponents"; import NextButton from "../NextButton"; import PrevButton from "../PrevButton"; import ImageViewer from "../ImageViewer"; import MobileDetails from "../MobileDetails"; import DesktopDetails from "../DesktopDetails"; import ViewerPlayer from "../ViewerPlayer/viewer-player"; import type ViewerProps from "./Viewer.props"; function Viewer(props: ViewerProps) { const timerIDRef = useRef(); const containerRef = React.useRef(document.createElement("div")); const [panelVisible, setPanelVisible] = useState(true); const [isOpenContextMenu, setIsOpenContextMenu] = useState(false); const [isError, setIsError] = useState(false); const [isPlay, setIsPlay] = useState(null); const [imageTimer, setImageTimer] = useState(); const panelVisibleRef = useRef(false); const contextMenuRef = useRef(null); const videoElementRef = useRef(null); const [isFullscreen, setIsFullScreen] = useState(false); useEffect(() => { document.body.appendChild(containerRef.current); return () => { document.body.removeChild(containerRef.current); timerIDRef.current && clearTimeout(timerIDRef.current); }; }, []); useEffect(() => { if ((!isPlay || isOpenContextMenu) && (!props.isImage || isOpenContextMenu)) return clearTimeout(timerIDRef.current); }, [isPlay, isOpenContextMenu, props.isImage]); const resetToolbarVisibleTimer = () => { if (panelVisibleRef.current) { clearTimeout(timerIDRef.current); timerIDRef.current = setTimeout(() => { panelVisibleRef.current = false; setPanelVisible(false); }, 2500); } else { setPanelVisible(true); panelVisibleRef.current = true; timerIDRef.current = setTimeout(() => { panelVisibleRef.current = false; setPanelVisible(false); }, 2500); } }; useEffect(() => { if (isMobile) return; document.addEventListener("mousemove", resetToolbarVisibleTimer, { passive: true, }); return () => { document.removeEventListener("mousemove", resetToolbarVisibleTimer); clearTimeout(timerIDRef.current); setPanelVisible(true); }; }, [setImageTimer, setPanelVisible]); useEffect(() => { document.addEventListener("touchstart", onTouch); return () => document.removeEventListener("touchstart", onTouch); }, [setPanelVisible]); const onTouch = useCallback( (e: TouchEvent, canTouch?: boolean) => { if (e.target === videoElementRef.current || canTouch) { setPanelVisible((visible) => !visible); } }, [setPanelVisible] ); const nextClick = () => { clearTimeout(imageTimer); props.onNextClick(); }; const prevClick = () => { clearTimeout(imageTimer); props.onPrevClick(); }; const onMobileContextMenu = useCallback( (e: TouchEvent) => { setIsOpenContextMenu((open) => !open); props.onSetSelectionFile(); contextMenuRef.current?.show(e); }, [props.onSetSelectionFile, setIsOpenContextMenu] ); const onHide = useCallback(() => { setIsOpenContextMenu(false); }, [setIsOpenContextMenu]); const mobileDetails = ( ); const displayUI = (isMobileOnly && props.isAudio) || panelVisible; const isNotFirstElement = props.playlistPos !== 0; const isNotLastElement = props.playlistPos < props.playlist.length - 1; return ( {!isFullscreen && !isMobile && panelVisible && ( )} {props.playlist.length > 1 && !isFullscreen && !isMobile && ( <> {isNotFirstElement && } {isNotLastElement && } )} {props.isImage ? ReactDOM.createPortal( , containerRef.current ) : (props.isVideo || props.isAudio) && ReactDOM.createPortal( , containerRef.current )} ); } export default Viewer;