diff --git a/apps/desktop/src/App.tsx b/apps/desktop/src/App.tsx index f5a8dd3..0df7de1 100644 --- a/apps/desktop/src/App.tsx +++ b/apps/desktop/src/App.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import { tauriGateway } from './lib/tauriGateway'; import { PdfViewer } from './components/PdfViewer'; import { ErrorBoundary } from './components/ErrorBoundary'; +import { createViewerRenderer } from './lib/viewerRenderer'; import type { ExtractedPageTextRecord, RecentDocumentView } from '@gitplant/shared-types'; export function App() { @@ -90,6 +91,7 @@ export function App() { bytes={bytes} overlayBytes={overlayBytes} title={title} + rendererFactory={createViewerRenderer} onPageCount={(n) => { if (currentRevisionId) void tauriGateway.updatePageCount(currentRevisionId, n); }} diff --git a/apps/desktop/src/components/PdfViewer.test.tsx b/apps/desktop/src/components/PdfViewer.test.tsx index 399128c..bee157e 100644 --- a/apps/desktop/src/components/PdfViewer.test.tsx +++ b/apps/desktop/src/components/PdfViewer.test.tsx @@ -21,7 +21,10 @@ describe('PdfViewer states', () => { it('ui-level code avoids direct pdfjs imports', () => { const appSource = fs.readFileSync(path.resolve(__dirname, '../App.tsx'), 'utf8'); + const viewerSource = fs.readFileSync(path.resolve(__dirname, './PdfViewer.tsx'), 'utf8'); expect(appSource).not.toContain('pdfjs-dist'); expect(appSource).not.toContain('@gitplant/viewer-pdfjs'); + expect(viewerSource).not.toContain('pdfjs-dist'); + expect(viewerSource).not.toContain('@gitplant/viewer-pdfjs'); }); }); diff --git a/apps/desktop/src/components/PdfViewer.tsx b/apps/desktop/src/components/PdfViewer.tsx index b378949..b0d0301 100644 --- a/apps/desktop/src/components/PdfViewer.tsx +++ b/apps/desktop/src/components/PdfViewer.tsx @@ -1,16 +1,16 @@ import { useEffect, useMemo, useState } from 'react'; -import { createBaseRenderScene, withOverlayPdfLayer } from '@gitplant/viewer-core'; -import { PdfjsRendererAdapter } from '@gitplant/viewer-pdfjs'; +import { createBaseRenderScene, withOverlayPdfLayer, type ViewerRenderer } from '@gitplant/viewer-core'; type Props = { bytes: Uint8Array | null; title: string; overlayBytes?: Uint8Array | null; onPageCount?: (n: number) => void; + rendererFactory?: () => ViewerRenderer; }; -export function PdfViewer({ bytes, title, overlayBytes, onPageCount }: Props) { - const renderer = useMemo(() => new PdfjsRendererAdapter(), []); +export function PdfViewer({ bytes, title, overlayBytes, onPageCount, rendererFactory }: Props) { + const renderer = useMemo(() => (rendererFactory ? rendererFactory() : null), [rendererFactory]); const [page, setPage] = useState(1); const [pageCount, setPageCount] = useState(0); const [zoom, setZoom] = useState(1); @@ -20,7 +20,7 @@ export function PdfViewer({ bytes, title, overlayBytes, onPageCount }: Props) { useEffect(() => { void (async () => { - if (!bytes) return; + if (!bytes || !renderer) return; setState('loading'); try { await renderer.openDocument(bytes); @@ -38,13 +38,13 @@ export function PdfViewer({ bytes, title, overlayBytes, onPageCount }: Props) { } })(); return () => { - void renderer.closeDocument(); + if (renderer) void renderer.closeDocument(); }; - }, [bytes, overlayBytes]); + }, [bytes, overlayBytes, renderer]); useEffect(() => { void (async () => { - if (!bytes || state === 'error' || pageCount === 0) return; + if (!bytes || !renderer || state === 'error' || pageCount === 0) return; setState('loading'); try { const nextScene = { @@ -63,6 +63,7 @@ export function PdfViewer({ bytes, title, overlayBytes, onPageCount }: Props) { }, [page, zoom]); if (!bytes) return