2023-11-03 07:11:33 -04:00
|
|
|
import { FC, useCallback } from 'react'
|
|
|
|
import useIsMounted from '@/shared/hooks/use-is-mounted'
|
|
|
|
import { useFileTreePathContext } from '@/features/file-tree/contexts/file-tree-path'
|
|
|
|
import { debugConsole } from '@/utils/debugging'
|
|
|
|
|
|
|
|
const FileViewPdf: FC<{
|
|
|
|
fileId: string
|
|
|
|
onLoad: () => void
|
|
|
|
onError: () => void
|
|
|
|
}> = ({ fileId, onLoad, onError }) => {
|
|
|
|
const mountedRef = useIsMounted()
|
|
|
|
|
2023-11-06 08:08:52 -05:00
|
|
|
const { previewByPath, pathInFolder } = useFileTreePathContext()
|
2023-11-03 07:11:33 -04:00
|
|
|
|
|
|
|
const handleContainer = useCallback(
|
|
|
|
async (element: HTMLDivElement | null) => {
|
|
|
|
if (element) {
|
|
|
|
const { PDFJS } = await import(
|
|
|
|
'../../pdf-preview/util/pdf-js-versions'
|
|
|
|
).then(m => m.default as any)
|
|
|
|
|
|
|
|
// bail out if loading PDF.js took too long
|
|
|
|
if (!mountedRef.current) {
|
|
|
|
onError()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-11-06 08:08:52 -05:00
|
|
|
const path = pathInFolder(fileId)
|
|
|
|
const preview = path ? previewByPath(path) : null
|
2023-11-03 07:11:33 -04:00
|
|
|
|
|
|
|
if (!preview) {
|
|
|
|
onError()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const pdf = await PDFJS.getDocument(preview.url).promise
|
|
|
|
|
2023-12-05 04:41:06 -05:00
|
|
|
// bail out if loading the PDF took too long
|
|
|
|
if (!mountedRef.current) {
|
|
|
|
onError()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
element.textContent = '' // ensure the element is empty
|
|
|
|
|
2023-11-08 07:07:43 -05:00
|
|
|
const scale = window.devicePixelRatio || 1
|
|
|
|
|
2023-11-03 07:11:33 -04:00
|
|
|
for (let i = 1; i <= pdf.numPages; i++) {
|
|
|
|
const page = await pdf.getPage(i)
|
2023-11-08 07:07:43 -05:00
|
|
|
const viewport = page.getViewport({ scale })
|
2023-11-03 07:11:33 -04:00
|
|
|
|
|
|
|
const canvas = document.createElement('canvas')
|
|
|
|
canvas.classList.add('pdf-page')
|
|
|
|
canvas.width = viewport.width
|
|
|
|
canvas.height = viewport.height
|
2023-11-08 07:07:43 -05:00
|
|
|
canvas.style.width = `${viewport.width / scale}px`
|
|
|
|
canvas.style.height = `${viewport.height / scale}px`
|
|
|
|
|
2023-11-03 07:11:33 -04:00
|
|
|
element.append(canvas)
|
|
|
|
page.render({
|
|
|
|
canvasContext: canvas.getContext('2d'),
|
|
|
|
viewport,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
onLoad()
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
pdf.cleanup().catch(debugConsole.error)
|
|
|
|
pdf.destroy()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2023-11-06 08:08:52 -05:00
|
|
|
[mountedRef, pathInFolder, fileId, previewByPath, onLoad, onError]
|
2023-11-03 07:11:33 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
return <div className="file-view-pdf" ref={handleContainer} />
|
|
|
|
}
|
|
|
|
|
|
|
|
export default FileViewPdf
|