import React, { useEffect, useState, useCallback } from 'react'; import MobileDetect from 'mobile-detect'; import Icon from '../components/Icon'; import Button from '../components/Button'; import ExpansionPanel from '../components/ExpansionPanel'; import HighlightOption from '../components/HighlightOption'; import useActions from '../actions'; import useStore from '../store'; import { getMarkupWithSelection } from '../helpers/markup'; type Props = { title: string; isActive: boolean; onClick: () => void; }; let timer = 0; let textLayer: HTMLElement | null = null; const HighlightTools: React.FC = ({ title, isActive, onClick, }: Props) => { const [currentId, setCurrentId] = useState(''); const [data, setData] = useState({ type: 'highlight', color: '#FBB705', opacity: 35, }); const [{ scale, annotations }, dispatch] = useStore(); const { addAnnots, updateAnnots } = useActions(dispatch); const setDataState = (obj: OptionPropsType): void => { setData((prev) => ({ ...prev, ...obj, })); }; const handleDown = () => { timer = setTimeout(() => { setCurrentId(''); }, 1500); }; const handleMove = () => { if (timer) { clearTimeout(timer); } }; const handleUp = useCallback( (e: MouseEvent | TouchEvent): void => { const selection = document.getSelection(); if (!selection?.isCollapsed && !currentId) { if (e.target) { textLayer = (e.target as HTMLElement).parentNode as HTMLElement; if (textLayer.getAttribute('data-id') !== 'text-layer') { textLayer = textLayer.querySelector( '[data-id="text-layer"]', ) as HTMLElement; } if (textLayer) { textLayer.style.zIndex = '10'; const newMarkup = getMarkupWithSelection({ ...data, scale, textLayer, }); if (newMarkup) { setCurrentId(newMarkup.id as string); addAnnots([newMarkup]); } } } } if (selection?.isCollapsed) { if (textLayer) { textLayer.style.zIndex = '0'; } setCurrentId(''); } }, [data, scale, currentId], ); const handleSelectStart = () => { setCurrentId(''); }; const handleSelectChange = useCallback(() => { const selection = document.getSelection(); if (!selection?.isCollapsed && currentId) { if (textLayer) { const newMarkup = getMarkupWithSelection({ ...data, scale, textLayer, }); if (newMarkup) { const array: AnnotationType[] = []; annotations.forEach((ele) => { if (ele.id === currentId) { // eslint-disable-next-line no-param-reassign ele.obj_attr.position = newMarkup.obj_attr.position; } array.push(ele); }); updateAnnots(array); } } } }, [annotations, data, scale, currentId]); useEffect(() => { const md = new MobileDetect(window.navigator.userAgent); if (isActive) { document.addEventListener('mousedown', handleDown); document.addEventListener('mousemove', handleMove); document.addEventListener('mouseup', handleUp); document.addEventListener('selectstart', handleSelectStart); if (md.mobile() || md.tablet()) { document.addEventListener('touchstart', handleDown); document.addEventListener('touchmove', handleMove); document.addEventListener('touchend', handleUp); document.addEventListener('selectionchange', handleSelectChange); } } else if (textLayer) { textLayer.style.zIndex = '0'; } return (): void => { document.removeEventListener('mousedown', handleDown); document.removeEventListener('mousemove', handleMove); document.removeEventListener('mouseup', handleUp); document.removeEventListener('selectstart', handleSelectStart); if (md.mobile() || md.tablet()) { document.removeEventListener('touchstart', handleDown); document.removeEventListener('touchmove', handleMove); document.removeEventListener('touchend', handleUp); document.removeEventListener('selectionchange', handleSelectChange); } }; }, [isActive, handleUp, handleSelectChange]); const Label = ( ); return ( ); }; export default HighlightTools;