diff --git a/app/pdf-viewer.tsx b/app/pdf-viewer.tsx index 378c719..cf037c7 100644 --- a/app/pdf-viewer.tsx +++ b/app/pdf-viewer.tsx @@ -46,6 +46,15 @@ export default function PdfViewerScreen() { const [showTocModal, setShowTocModal] = useState(false); const [showViewModeModal, setShowViewModeModal] = useState(false); const [isSharing, setIsSharing] = useState(false); + const [pdfMounted, setPdfMounted] = useState(true); + + const switchViewMode = (mode: "single" | "continuous") => { + // Unmount the PDF component first to let the native rendering thread finish + // before the document is closed, avoiding IllegalStateException: Already closed + setPdfMounted(false); + setViewMode(mode); + requestAnimationFrame(() => setPdfMounted(true)); + }; useEffect(() => { if (Platform.OS === "android") { @@ -127,26 +136,28 @@ export default function PdfViewerScreen() { ), }} /> - { - setTotalPages(numberOfPages); - setTableOfContents(toc ?? []); - }} - onPageChanged={(page) => setCurrentPage(page)} - onError={(error) => { - Sentry.captureException(error); - console.error("PDF Error:", error); - }} - /> + {pdfMounted && ( + { + setTotalPages(numberOfPages); + setTableOfContents(toc ?? []); + }} + onPageChanged={(page) => setCurrentPage(page)} + onError={(error) => { + Sentry.captureException(error); + console.error("PDF Error:", error); + }} + /> + )} setShowTocModal(false)}> @@ -181,7 +192,7 @@ export default function PdfViewerScreen() { { - setViewMode("single"); + switchViewMode("single"); setShowViewModeModal(false); }} className="flex-row items-center justify-between border-b border-border py-4" @@ -194,7 +205,7 @@ export default function PdfViewerScreen() { { - setViewMode("continuous"); + switchViewMode("continuous"); setShowViewModeModal(false); }} className="flex-row items-center justify-between border-b border-border py-4"