({
showSearch,
setShowSearch,
showThumbnails,
url: initialUrl,
}: PdfViewerProps)
| 105 | }; |
| 106 | |
| 107 | export const PdfPreview = ({ |
| 108 | showSearch, |
| 109 | setShowSearch, |
| 110 | showThumbnails, |
| 111 | url: initialUrl, |
| 112 | }: PdfViewerProps) => { |
| 113 | const [url, setUrl] = useState(""); |
| 114 | |
| 115 | useEffect(() => { |
| 116 | /** |
| 117 | * The API normally handles file downloads by: |
| 118 | * 1. Accepting a request with a cookie |
| 119 | * 2. Checking if the authenticated user can access the file |
| 120 | * 3. Automatically redirecting the request to a presigned URL to fetch the file |
| 121 | * |
| 122 | * This doesn't work for JS fetch because the request to the redirected URL will have origin: null, |
| 123 | * which the object storage's CORS headers don't permit (at least in our deployed configuration). |
| 124 | * So we instead ask the API for the presigned URL only, and pass that to react-pdf. |
| 125 | */ |
| 126 | void fetch(`${initialUrl}?urlOnly=true`, { credentials: "include" }) |
| 127 | .then((resp) => resp.json()) |
| 128 | .then((response) => { |
| 129 | setUrl(response.url); |
| 130 | }); |
| 131 | }, [initialUrl]); |
| 132 | |
| 133 | const [documentProxy, setDocumentProxy] = useState<DocumentCallback | null>( |
| 134 | null, |
| 135 | ); |
| 136 | const [scale, setScale] = useState(1); |
| 137 | const [totalPages, setTotalPages] = useState<number>(); |
| 138 | const [selectedPageNumber, setSelectedPageNumber] = useState<number>(1); |
| 139 | const [searchHits, setSearchHits] = useState<SearchHits>({ |
| 140 | total: 0, |
| 141 | hitsByPageNumber: {}, |
| 142 | }); |
| 143 | const [selectedSearchHit, setSelectedSearchHit] = useState<SearchHit | null>( |
| 144 | null, |
| 145 | ); |
| 146 | |
| 147 | const onDocumentLoadSuccess: OnDocumentLoadSuccess = (docProxy) => { |
| 148 | setTotalPages(docProxy.numPages); |
| 149 | setDocumentProxy(docProxy); |
| 150 | }; |
| 151 | |
| 152 | const textRenderer: CustomTextRenderer = useCallback( |
| 153 | (textItem) => { |
| 154 | const relevantSearchHits = |
| 155 | searchHits.hitsByPageNumber[textItem.pageNumber] ?? []; |
| 156 | |
| 157 | if (!relevantSearchHits.length) { |
| 158 | return textItem.str; |
| 159 | } |
| 160 | |
| 161 | return highlightOccurrencesInTextItem( |
| 162 | textItem.str, |
| 163 | textItem.itemIndex, |
| 164 | relevantSearchHits, |
nothing calls this directly
no test coverage detected