(props)
| 31 | import { useScroll } from "../../context/ScrollPdfContext"; |
| 32 | |
| 33 | function RenderPdf(props) { |
| 34 | const { t } = useTranslation(); |
| 35 | const dispatch = useDispatch(); |
| 36 | const { showGuidelines, showCanvasGuidelines } = useGuidelinesContext(); |
| 37 | // Ref to store per-page DOM elements for scroll-based page tracking & scroll |
| 38 | const pageRefs = useRef({}); |
| 39 | // Ref to defer DnD drops that land on a page different from the current one |
| 40 | const pendingDropRef = useRef(null); |
| 41 | // Ref to suppress scroll-handler updates during programmatic scrolling |
| 42 | const isScrollingToPage = useRef(false); |
| 43 | // Stores the page number most recently set BY the scroll handler. The |
| 44 | // page-change effect compares props.pageNumber against this value to detect |
| 45 | // whether the change came from scrolling (skip programmatic scroll) or from |
| 46 | // an external action like a thumbnail/chevron click (do programmatic scroll). |
| 47 | // Using a page-number value instead of a boolean flag avoids a stuck-true |
| 48 | // scenario: when React bails out of setPageNumber because the value hasn't |
| 49 | // changed, no re-render fires and a boolean flag would never get reset. |
| 50 | const lastScrollSetPage = useRef(null); |
| 51 | // Ref tracking the last detected page – used to narrow the per-scroll scan |
| 52 | const lastBestPage = useRef(1); |
| 53 | // Pending requestAnimationFrame id for scroll throttling (null = none pending) |
| 54 | const scrollRafId = useRef(null); |
| 55 | const { scrollRef } = useScroll(); |
| 56 | // Internal count of total pages (set from Document onLoadSuccess) |
| 57 | const [allPagesCount, setAllPagesCount] = useState(0); |
| 58 | const isWidgetDrop = useRef(false); |
| 59 | const [, drop] = useDrop({ |
| 60 | accept: "BOX", |
| 61 | drop: (item, monitor) => { |
| 62 | isWidgetDrop.current = true; |
| 63 | setTimeout(() => { |
| 64 | isWidgetDrop.current = false; |
| 65 | }, 600); |
| 66 | const offset = monitor.getClientOffset(); |
| 67 | // Multi-page: detect target page and swap #container to it |
| 68 | if (allPagesCount > 1 && offset) { |
| 69 | let targetPage = props.pageNumber; |
| 70 | for (let i = 1; i <= allPagesCount; i++) { |
| 71 | const el = pageRefs.current[i]; |
| 72 | if (el) { |
| 73 | const rect = el.getBoundingClientRect(); |
| 74 | if (offset.y >= rect.top && offset.y <= rect.bottom) { |
| 75 | targetPage = i; |
| 76 | break; |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | if (targetPage !== props.pageNumber && props.setPageNumber) { |
| 81 | // Defer: store drop info, update page, handle in useEffect |
| 82 | props.setPageNumber(targetPage); |
| 83 | pendingDropRef.current = { |
| 84 | item, |
| 85 | offset: { ...offset }, |
| 86 | targetPage |
| 87 | }; |
| 88 | showGuidelines(false); |
| 89 | return; |
| 90 | } |
nothing calls this directly
no test coverage detected