123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import React, { useEffect, useState, useCallback } from 'react';
- import { ANNOTATION_TYPE } from '../constants';
- import Icon from '../components/Icon';
- import Button from '../components/Button';
- import ExpansionPanel from '../components/ExpansionPanel';
- import FreeTextOption from '../components/FreeTextOption';
- import { getAbsoluteCoordinate } from '../helpers/position';
- import {
- parseAnnotationObject,
- appendUserIdAndDate,
- } from '../helpers/annotation';
- import useActions from '../actions';
- import useStore from '../store';
- type Props = {
- title: string;
- isActive: boolean;
- onClick: () => void;
- };
- const HighlightTool: React.FC<Props> = ({
- title,
- isActive,
- onClick,
- }: Props) => {
- const [data, setData] = useState({
- fontName: 'Helvetica',
- fontSize: 18,
- align: 'left',
- fontStyle: '',
- color: '#FBB705',
- opacity: 100,
- });
- const [{ viewport, scale }, dispatch] = useStore();
- const { addAnnots } = useActions(dispatch);
- const setDataState = (obj: OptionPropsType): void => {
- setData((prev) => ({
- ...prev,
- ...obj,
- }));
- };
- const addFreeText = (
- pageEle: HTMLElement,
- event: MouseEvent | TouchEvent,
- attributes: OptionPropsType,
- ): void => {
- const {
- fontStyle,
- fontName,
- fontSize = 0,
- opacity,
- color,
- align,
- } = attributes;
- const pageNum = pageEle.getAttribute('data-page-num') || 0;
- const coordinate = getAbsoluteCoordinate(pageEle, event);
- const annotData = {
- obj_type: ANNOTATION_TYPE.freetext,
- obj_attr: {
- page: pageNum as number,
- position: {
- top: coordinate.y,
- left: coordinate.x,
- bottom: coordinate.y + fontSize * scale,
- right: coordinate.x + 30,
- },
- transparency: opacity,
- fontname: fontStyle ? `${fontName}-${fontStyle}` : fontName,
- fontsize: fontSize,
- textcolor: color,
- align,
- content: '',
- },
- };
- const freeText = appendUserIdAndDate(
- parseAnnotationObject(annotData, viewport.height, scale),
- );
- addAnnots([freeText]);
- };
- const handleMouseDown = useCallback(
- (event: MouseEvent | TouchEvent): void => {
- const pageEle = (event.target as HTMLElement).parentNode as HTMLElement;
- if (pageEle.hasAttribute('data-page-num')) {
- addFreeText(pageEle, event, data);
- }
- },
- [data, viewport, scale],
- );
- useEffect(() => {
- const pdfViewer = document.getElementById('pdf_viewer') as HTMLDivElement;
- if (pdfViewer) {
- if (isActive) {
- pdfViewer.addEventListener('mousedown', handleMouseDown);
- pdfViewer.addEventListener('touchstart', handleMouseDown);
- } else {
- pdfViewer.removeEventListener('mousedown', handleMouseDown);
- pdfViewer.removeEventListener('touchstart', handleMouseDown);
- }
- }
- return (): void => {
- if (pdfViewer) {
- pdfViewer.removeEventListener('mousedown', handleMouseDown);
- pdfViewer.removeEventListener('touchstart', handleMouseDown);
- }
- };
- }, [isActive, handleMouseDown]);
- const Label = (
- <Button
- shouldFitContainer
- align="left"
- onClick={onClick}
- isActive={isActive}
- >
- <Icon glyph="text" style={{ marginRight: '10px' }} />
- {title}
- </Button>
- );
- return (
- <ExpansionPanel label={Label} isActive={isActive} showBottomBorder>
- <FreeTextOption {...data} setDataState={setDataState} />
- </ExpansionPanel>
- );
- };
- export default HighlightTool;
|