StickyNoteTool.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import React, { useEffect, useCallback } from 'react';
  2. import { ANNOTATION_TYPE } from '../constants';
  3. import Button from '../components/Button';
  4. import Icon from '../components/Icon';
  5. import { getAbsoluteCoordinate } from '../helpers/position';
  6. import {
  7. parseAnnotationObject,
  8. appendUserIdAndDate,
  9. } from '../helpers/annotation';
  10. import { BtnWrapper } from '../global/toolStyled';
  11. import useActions from '../actions';
  12. import useStore from '../store';
  13. type Props = {
  14. title: string;
  15. isActive: boolean;
  16. onClick: () => void;
  17. };
  18. const StickyNoteTool: React.FC<Props> = ({
  19. title,
  20. isActive,
  21. onClick,
  22. }: Props) => {
  23. const [{ viewport, scale }, dispatch] = useStore();
  24. const { addAnnots } = useActions(dispatch);
  25. const addStickyNote = (
  26. pageEle: HTMLElement,
  27. event: MouseEvent | TouchEvent
  28. ): void => {
  29. const pageNum = pageEle.getAttribute('data-page-num') || 0;
  30. const coordinate = getAbsoluteCoordinate(pageEle, event);
  31. const annotData = {
  32. obj_type: ANNOTATION_TYPE.text,
  33. obj_attr: {
  34. page: pageNum as number,
  35. position: {
  36. top: coordinate.y,
  37. left: coordinate.x,
  38. bottom: coordinate.y + 20,
  39. right: coordinate.x + 20,
  40. },
  41. content: '',
  42. },
  43. };
  44. const stickyNote = appendUserIdAndDate(
  45. parseAnnotationObject(annotData, viewport.height, scale)
  46. );
  47. addAnnots([stickyNote]);
  48. };
  49. const handleMouseDown = useCallback(
  50. (event: MouseEvent | TouchEvent): void => {
  51. const pageEle = (event.target as HTMLElement).parentNode as HTMLElement;
  52. if (pageEle.hasAttribute('data-page-num')) {
  53. addStickyNote(pageEle, event);
  54. }
  55. },
  56. [viewport, scale]
  57. );
  58. useEffect(() => {
  59. const pdfViewer = document.getElementById('pdf_viewer') as HTMLDivElement;
  60. if (isActive && pdfViewer) {
  61. window.addEventListener('touchstart', handleMouseDown);
  62. window.addEventListener('mousedown', handleMouseDown);
  63. }
  64. return (): void => {
  65. if (pdfViewer) {
  66. window.removeEventListener('touchstart', handleMouseDown);
  67. window.removeEventListener('mousedown', handleMouseDown);
  68. }
  69. };
  70. }, [isActive, handleMouseDown]);
  71. return (
  72. <BtnWrapper>
  73. <Button
  74. shouldFitContainer
  75. align="left"
  76. onClick={onClick}
  77. isActive={isActive}
  78. >
  79. <Icon glyph="sticky-note" style={{ marginRight: '10px' }} />
  80. {title}
  81. </Button>
  82. </BtnWrapper>
  83. );
  84. };
  85. export default StickyNoteTool;