import React, { memo, useEffect, useState } from "react"; import { useClickOutOfBounds, useUtils } from "../../hooks/utils"; import TrashIcon from "../../icons/TrashIcon"; import MultiSelectIcon from "../../icons/MultiSelectIcon"; import RenameIcon from "../../icons/RenameIcon"; import ShareIcon from "../../icons/ShareIcon"; import DownloadIcon from "../../icons/DownloadIcon"; import MoveIcon from "../../icons/MoveIcon"; import RestoreIcon from "../../icons/RestoreIcon"; import { FileInterface } from "../../types/file"; import { useNavigate } from "react-router-dom"; import { useActions } from "../../hooks/actions"; import { FolderInterface } from "../../types/folders"; export interface ContextMenuProps { closeContext: () => void; contextSelected: { selected: boolean; X: number; Y: number; }; folderMode?: boolean; quickItemMode?: boolean; parentBarMode?: boolean; file?: FileInterface | null; folder?: FolderInterface | null; stopPropagation?: () => void; } const ContextMenu: React.FC = memo((props) => { const [fixedCoords, setFixedCoords] = useState({ X: 0, Y: 0, set: false, }); const { closeContext, contextSelected, folderMode, file, quickItemMode, stopPropagation, folder, parentBarMode, } = props; const { wrapperRef } = useClickOutOfBounds(closeContext); const { isTrash, isMedia } = useUtils(); const navigate = useNavigate(); const { renameItem, trashItem, deleteItem, restoreItem, openMoveItemModal, openShareItemModal, downloadItem, selectItemMultiSelect, } = useActions({ quickItemMode }); useEffect(() => { if (!wrapperRef.current) return; const modalWidth = wrapperRef.current.clientWidth; const modalHeight = wrapperRef.current.clientHeight; const { innerWidth: windowWidth, innerHeight: windowHeight } = window; let X = contextSelected.X; let Y = contextSelected.Y; if (X + modalWidth > windowWidth) { X = windowWidth - modalWidth - 10; } if (Y + modalHeight > windowHeight) { Y = windowHeight - modalHeight - 10; } setFixedCoords({ X, Y, set: true, }); }, [wrapperRef, contextSelected.X, contextSelected.Y]); const onAction = async ( action: | "rename" | "trash" | "delete" | "restore" | "move" | "share" | "download" | "multi-select" ) => { closeContext(); switch (action) { case "rename": await renameItem(file, folder); break; case "trash": await trashItem(file, folder); break; case "delete": await deleteItem(file, folder); break; case "restore": await restoreItem(file, folder); break; case "move": await openMoveItemModal(file, folder); break; case "share": openShareItemModal(file); break; case "download": downloadItem(file, folder); break; case "multi-select": selectItemMultiSelect(file, folder); } if ( folder && parentBarMode && ["trash", "delete", "restore"].includes(action) ) { if (folder.parent === "/") { navigate("/trash"); } else { navigate(`/folder-trash/${folder.parent}`); } } }; const outterWrapperClick = (e: React.MouseEvent) => { e.stopPropagation(); if ((e.target as HTMLDivElement).id !== "context-wrapper") { return; } closeContext(); }; return (
{!parentBarMode && (
onAction("multi-select")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary rounded-t-md" >

Multi-select

)} {!isTrash && !isMedia && (
onAction("rename")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary" >

Rename

)} {!folderMode && !isTrash && (
onAction("share")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary" >

Share

)} {!isTrash && (
onAction("download")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary" >

Download

)} {!isTrash && !isMedia && (
onAction("move")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary" >

Move

)} {!isTrash && (
onAction("trash")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary rounded-b-md" >

Trash

)} {isTrash && (
onAction("restore")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary" >

Restore

)} {isTrash && (
onAction("delete")} className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-red-500 rounded-b-md" >

Delete

)}
); }); export default ContextMenu;