import { useMemo } from 'react'; import { AppWindow, Archive, ArrowRight, ArrowUp, ClipboardCopy, Copy, Download, Edit2, ExternalLink, FilePlus, Folder, FolderInput, FolderPlus, Pencil, RefreshCw, Shield, Trash2, Upload } from 'lucide-react'; import { ContextMenuContent, ContextMenuItem, ContextMenuSeparator } from '../ui/context-menu'; import { getParentPath } from '../../application/state/sftp/utils'; import { isKnownBinaryFile } from '../../lib/sftpFileUtils'; import { isExtractableArchive } from '../../domain/sftpArchive'; import { isNavigableDirectory } from './utils'; import { getSftpTreeUploadFilesTargetPath, getSftpUploadFilesLabelKey, getSftpUploadFolderLabelKey } from './sftpUploadMenu'; // eslint-disable-next-line @typescript-eslint/no-explicit-any type SftpPaneTreeContextMenuProps = Record; export function useSftpPaneTreeContextMenu(props: SftpPaneTreeContextMenuProps) { const { contextTarget, pane, toggleExpand, stableOnOpenEntry, stableOnRefresh, getActionPaths, toTransferSources, executeMoveAction, triggerUploadPicker, onUploadExternalFolder, uploadEnabled, folderUploadEnabled, setMoveTargetPaths, setMoveToPath, setMoveToError, setMoveToSuggestions, setMoveToSuggestionIndex, setIsMoving, setShowMoveToDialog, tRef, onCopyToOtherPaneRef, onNavigateToRef, onOpenFileWithSystemDefaultRef, onOpenFileWithRef, onEditFileRef, onDownloadFileRef, onExtractArchiveRef, onEditPermissionsRef, openDeleteConfirmRef, openRenameDialogRef, openNewFolderDialogRef, openNewFileDialogRef, } = props; return useMemo(() => { const target = contextTarget; if (!target) return null; const { entry, entryPath } = target; const isDir = isNavigableDirectory(entry); const isLocal = pane.connection?.isLocal; const handleOpen = () => { if (isDir) void toggleExpand(entry, entryPath); else stableOnOpenEntry(entry, entryPath); }; const handleCopyToOtherPane = () => { const paths = getActionPaths(entryPath); const files = toTransferSources(paths); if (files.length === 0) { files.push({ name: entry.name, isDirectory: isDir, sourceConnectionId: pane.connection?.id, sourcePath: getParentPath(entryPath), }); } onCopyToOtherPaneRef.current(files); }; const handleDelete = () => { openDeleteConfirmRef.current(getActionPaths(entryPath)); }; return ( {isDir ? <>{tRef.current('sftp.context.open')} : <>{tRef.current('sftp.context.open')}} {isDir && ( onNavigateToRef.current(entryPath)}> {tRef.current('sftp.context.navigateTo')} )} {!isDir && onOpenFileWithSystemDefaultRef.current && ( onOpenFileWithSystemDefaultRef.current?.(entry, entryPath)}> {tRef.current('sftp.context.openWithDefault')} )} {!isDir && onOpenFileWithRef.current && ( onOpenFileWithRef.current?.(entry, entryPath)}> {tRef.current('sftp.context.openWith')} )} {!isDir && !isKnownBinaryFile(entry.name) && onEditFileRef.current && ( onEditFileRef.current?.(entry, entryPath)}> {tRef.current('sftp.context.edit')} )} {onDownloadFileRef.current && (!isDir || !isLocal) && ( onDownloadFileRef.current?.(entry, entryPath)}> {tRef.current('sftp.context.download')} )} {!isDir && onExtractArchiveRef.current && isExtractableArchive(entry.name) && ( onExtractArchiveRef.current?.(entry, entryPath)}> {tRef.current('sftp.context.extract')} )} {tRef.current('sftp.context.copyToOtherPane')} navigator.clipboard.writeText(entryPath)}> {tRef.current('sftp.context.copyPath')} {(() => { const sourceParent = getParentPath(entryPath); const targetParent = getParentPath(sourceParent); if (sourceParent === targetParent) return null; return ( { const paths = getActionPaths(entryPath); void executeMoveAction(paths, targetParent); }}> {tRef.current('sftp.context.moveToParent')} ); })()} { setMoveTargetPaths(getActionPaths(entryPath)); setMoveToPath(''); setMoveToError(null); setMoveToSuggestions([]); setMoveToSuggestionIndex(-1); setIsMoving(false); setShowMoveToDialog(true); }}> {tRef.current('sftp.context.moveTo')} openRenameDialogRef.current(entryPath)}> {tRef.current('common.rename')} {onEditPermissionsRef.current && !isLocal && ( onEditPermissionsRef.current?.(entry, entryPath)}> {tRef.current('sftp.context.permissions')} )} {tRef.current('action.delete')} {tRef.current('common.refresh')} openNewFolderDialogRef.current(isDir ? entryPath : getParentPath(entryPath))}> {tRef.current('sftp.newFolder')} openNewFileDialogRef.current(isDir ? entryPath : getParentPath(entryPath))}> {tRef.current('sftp.newFile')} {uploadEnabled && ( { triggerUploadPicker(getSftpTreeUploadFilesTargetPath(entry, entryPath)); }} > {tRef.current(getSftpUploadFilesLabelKey(entry))} )} {folderUploadEnabled && ( { void onUploadExternalFolder?.(getSftpTreeUploadFilesTargetPath(entry, entryPath)); }} > {tRef.current(getSftpUploadFolderLabelKey(entry))} )} ); }, [ contextTarget, pane.connection?.isLocal, pane.connection?.id, toggleExpand, stableOnOpenEntry, stableOnRefresh, getActionPaths, toTransferSources, executeMoveAction, triggerUploadPicker, uploadEnabled, folderUploadEnabled, onUploadExternalFolder, onCopyToOtherPaneRef, onDownloadFileRef, onExtractArchiveRef, onEditFileRef, onEditPermissionsRef, onNavigateToRef, onOpenFileWithSystemDefaultRef, onOpenFileWithRef, openDeleteConfirmRef, openNewFileDialogRef, openNewFolderDialogRef, openRenameDialogRef, setIsMoving, setMoveTargetPaths, setMoveToError, setMoveToPath, setMoveToSuggestionIndex, setMoveToSuggestions, setShowMoveToDialog, tRef, ]); }