import { MAX_MENU_SIZE_MULTIPLIER, MENU_MARGIN_FROM_APP_BORDER } from '@/Constants' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside' import { AppState } from '@/UIModels/AppState' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'preact' import { useCallback, useEffect, useRef, useState } from 'preact/hooks' import React from 'react' import { PopoverFileItemAction } from '../AttachedFilesPopover/PopoverFileItemAction' import { PopoverTabs } from '../AttachedFilesPopover/PopoverTabs' import { FileMenuOptions } from './FileMenuOptions' type Props = { appState: AppState } export const FileContextMenu: FunctionComponent = observer(({ appState }) => { const { selectedFiles, showFileContextMenu, setShowFileContextMenu, fileContextMenuLocation } = appState.files const [contextMenuStyle, setContextMenuStyle] = useState({ top: 0, left: 0, visibility: 'hidden', }) const [contextMenuMaxHeight, setContextMenuMaxHeight] = useState('auto') const contextMenuRef = useRef(null) const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) => setShowFileContextMenu(open)) useCloseOnClickOutside(contextMenuRef, () => appState.files.setShowFileContextMenu(false)) const selectedFile = Object.values(selectedFiles)[0] if (!showFileContextMenu || !selectedFile) { return null } const reloadContextMenuLayout = useCallback(() => { const { clientHeight } = document.documentElement const defaultFontSize = window.getComputedStyle(document.documentElement).fontSize const maxContextMenuHeight = parseFloat(defaultFontSize) * MAX_MENU_SIZE_MULTIPLIER const footerElementRect = document.getElementById('footer-bar')?.getBoundingClientRect() const footerHeightInPx = footerElementRect?.height let openUpBottom = true if (footerHeightInPx) { const bottomSpace = clientHeight - footerHeightInPx - fileContextMenuLocation.y const upSpace = fileContextMenuLocation.y if (maxContextMenuHeight > bottomSpace) { if (upSpace > maxContextMenuHeight) { openUpBottom = false setContextMenuMaxHeight('auto') } else { if (upSpace > bottomSpace) { setContextMenuMaxHeight(upSpace - MENU_MARGIN_FROM_APP_BORDER) openUpBottom = false } else { setContextMenuMaxHeight(bottomSpace - MENU_MARGIN_FROM_APP_BORDER) } } } else { setContextMenuMaxHeight('auto') } } if (openUpBottom) { setContextMenuStyle({ top: fileContextMenuLocation.y, left: fileContextMenuLocation.x, visibility: 'visible', }) } else { setContextMenuStyle({ bottom: clientHeight - fileContextMenuLocation.y, left: fileContextMenuLocation.x, visibility: 'visible', }) } }, [fileContextMenuLocation.x, fileContextMenuLocation.y]) useEffect(() => { if (showFileContextMenu) { reloadContextMenuLayout() } }, [reloadContextMenuLayout, showFileContextMenu]) useEffect(() => { window.addEventListener('resize', reloadContextMenuLayout) return () => { window.removeEventListener('resize', reloadContextMenuLayout) } }, [reloadContextMenuLayout]) const handleFileAction = useCallback( async (action: PopoverFileItemAction) => { const { didHandleAction } = await appState.files.handleFileAction(action, PopoverTabs.AllFiles) return didHandleAction }, [appState.files], ) return (
setShowFileContextMenu(false)} shouldShowRenameOption={false} shouldShowAttachOption={false} />
) })