StickyNoteTool.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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 (pdfViewer) {
  61. if (isActive) {
  62. window.addEventListener('mousedown', handleMouseDown);
  63. window.addEventListener('touchstart', handleMouseDown);
  64. } else {
  65. window.removeEventListener('mousedown', handleMouseDown);
  66. window.removeEventListener('touchstart', handleMouseDown);
  67. }
  68. }
  69. return (): void => {
  70. if (pdfViewer) {
  71. window.removeEventListener('touchstart', handleMouseDown);
  72. window.removeEventListener('mousedown', handleMouseDown);
  73. }
  74. };
  75. }, [isActive, handleMouseDown]);
  76. return (
  77. <BtnWrapper>
  78. <Button
  79. shouldFitContainer
  80. align="left"
  81. onClick={onClick}
  82. isActive={isActive}
  83. >
  84. <Icon glyph="sticky-note" style={{ marginRight: '10px' }} />
  85. {title}
  86. </Button>
  87. </BtnWrapper>
  88. );
  89. };
  90. export default StickyNoteTool;