import { FC, HTMLProps, PropsWithChildren, useCallback, useEffect, useRef, useState, } from 'react' import { useTranslation } from 'react-i18next' import { EditorView } from '@codemirror/view' import { PastedContent } from '../../extensions/visual/pasted-content' import useEventListener from '../../../../shared/hooks/use-event-listener' import { sendMB } from '@/infrastructure/event-tracking' import MaterialIcon from '@/shared/components/material-icon' import OLOverlay from '@/shared/components/ol/ol-overlay' import OLPopover from '@/shared/components/ol/ol-popover' import { isMac } from '@/shared/utils/os' export const PastedContentMenu: FC<{ insertPastedContent: ( view: EditorView, pastedContent: PastedContent, formatted: boolean ) => void pastedContent: PastedContent view: EditorView formatted: boolean }> = ({ view, insertPastedContent, pastedContent, formatted }) => { const [menuOpen, setMenuOpen] = useState(false) const toggleButtonRef = useRef(null) const { t } = useTranslation() // record whether the Shift key is currently down, for use in the `paste` event handler const shiftRef = useRef(false) useEventListener( 'keydown', useCallback((event: KeyboardEvent) => { shiftRef.current = event.shiftKey }, []) ) // track interaction events const trackedEventsRef = useRef>({ 'pasted-content-button-shown': false, 'pasted-content-button-click': false, }) const trackEventOnce = useCallback((key: string) => { if (!trackedEventsRef.current[key]) { trackedEventsRef.current[key] = true sendMB(key) } }, []) useEffect(() => { if (menuOpen) { trackEventOnce('pasted-content-button-click') } else { trackEventOnce('pasted-content-button-shown') } }, [menuOpen, trackEventOnce]) useEffect(() => { if (menuOpen) { const abortController = new AbortController() view.dom.addEventListener( 'paste', event => { event.preventDefault() event.stopPropagation() insertPastedContent(view, pastedContent, !shiftRef.current) setMenuOpen(false) }, { signal: abortController.signal, capture: true } ) return () => { abortController.abort() } } }, [view, menuOpen, pastedContent, insertPastedContent]) // TODO: keyboard navigation return ( <> {menuOpen && ( setMenuOpen(false)} transition={false} container={view.scrollDOM} containerPadding={0} placement="bottom" rootClose target={toggleButtonRef?.current} > )} ) } const MenuItem = ({ children, ...buttonProps }: PropsWithChildren>) => ( )