import React, { createRef, useEffect, useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faEllipsisH } from '@fortawesome/free-solid-svg-icons/faEllipsisH'; import { CSSTransition } from 'react-transition-group'; import { faPencilAlt } from '@fortawesome/free-solid-svg-icons/faPencilAlt'; import { faTrashAlt } from '@fortawesome/free-solid-svg-icons/faTrashAlt'; import { faFileDownload } from '@fortawesome/free-solid-svg-icons/faFileDownload'; import { faCopy } from '@fortawesome/free-solid-svg-icons/faCopy'; import { faLevelUpAlt } from '@fortawesome/free-solid-svg-icons/faLevelUpAlt'; import RenameFileModal from '@/components/server/files/RenameFileModal'; import { ServerContext } from '@/state/server'; import CopyFileModal from '@/components/server/files/CopyFileModal'; import { join } from 'path'; import deleteFile from '@/api/server/files/deleteFile'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import copyFile from '@/api/server/files/copyFile'; import { httpErrorToHuman } from '@/api/http'; type ModalType = 'rename' | 'move'; export default ({ uuid }: { uuid: string }) => { const menu = createRef(); const [ visible, setVisible ] = useState(false); const [ showSpinner, setShowSpinner ] = useState(false); const [ modal, setModal ] = useState(null); const [ posX, setPosX ] = useState(0); const server = ServerContext.useStoreState(state => state.server.data!); const file = ServerContext.useStoreState(state => state.files.contents.find(file => file.uuid === uuid)); const directory = ServerContext.useStoreState(state => state.files.directory); const { removeFile, getDirectoryContents } = ServerContext.useStoreActions(actions => actions.files); if (!file) { return null; } const windowListener = (e: MouseEvent) => { if (e.button === 2 || !visible || !menu.current) { return; } if (e.target === menu.current || menu.current.contains(e.target as Node)) { return; } if (e.target !== menu.current && !menu.current.contains(e.target as Node)) { setVisible(false); } }; const doDeletion = () => { setShowSpinner(true); deleteFile(server.uuid, join(directory, file.name)) .then(() => removeFile(uuid)) .catch(error => { console.error('Error while attempting to delete a file.', error); setShowSpinner(false); }); }; const doCopy = () => { setShowSpinner(true); copyFile(server.uuid, join(directory, file.name)) .then(() => getDirectoryContents(directory)) .catch(error => { console.error('Error while attempting to copy file.', error); alert(httpErrorToHuman(error)); setShowSpinner(false); }); }; useEffect(() => { visible ? document.addEventListener('click', windowListener) : document.removeEventListener('click', windowListener); if (visible && menu.current) { menu.current.setAttribute( 'style', `margin-top: -0.35rem; left: ${Math.round(posX - menu.current.clientWidth)}px`, ); } }, [ visible ]); useEffect(() => () => { document.removeEventListener('click', windowListener); }, []); return (
{ e.preventDefault(); if (!visible) { setPosX(e.clientX); } else if (visible) { setModal(null); } setVisible(!visible); }} > {visible && setModal(null)}/> }
setModal('rename')} className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} > Rename
Move
doCopy()} className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} > Copy
Download
doDeletion()} className={'hover:text-red-700 p-2 flex items-center hover:bg-red-100 rounded'} > Delete
); };