This commit is contained in:
Reece 2025-07-10 20:20:03 +01:00
parent 83b8c9be09
commit 7694837764
2 changed files with 1 additions and 55 deletions

View File

@ -158,60 +158,25 @@ const Viewer = ({
const [zoom, setZoom] = useState(1); // 1 = 100% const [zoom, setZoom] = useState(1); // 1 = 100%
const pageRefs = useRef<(HTMLImageElement | null)[]>([]); const pageRefs = useRef<(HTMLImageElement | null)[]>([]);
// Store preview URL ref to manage lifecycle properly
const previewUrlRef = useRef<string | null>(null);
const currentPreviewFileRef = useRef<File | null>(null);
// Use preview file if available, otherwise use context file // Use preview file if available, otherwise use context file
const effectiveFile = React.useMemo(() => { const effectiveFile = React.useMemo(() => {
if (previewFile) { if (previewFile) {
// Clean up previous preview URL if it's different
if (previewUrlRef.current && currentPreviewFileRef.current !== previewFile) {
URL.revokeObjectURL(previewUrlRef.current);
previewUrlRef.current = null;
}
// Validate the preview file // Validate the preview file
if (!(previewFile instanceof File)) { if (!(previewFile instanceof File)) {
console.error('Preview file is not a valid File object:', previewFile);
return null; return null;
} }
if (previewFile.size === 0) { if (previewFile.size === 0) {
console.error('Preview file is empty:', previewFile.name);
return null; return null;
} }
if (previewFile.type !== 'application/pdf') {
console.warn('Preview file is not a PDF:', previewFile.type);
}
// For preview files, we'll handle loading differently (no URL needed)
// but we still need to return a consistent structure
currentPreviewFileRef.current = previewFile;
console.log('Preview file set:', { name: previewFile.name, size: previewFile.size, type: previewFile.type });
return { file: previewFile, url: null }; return { file: previewFile, url: null };
} else { } else {
// Clean up preview URL when switching away from preview
if (previewUrlRef.current) {
URL.revokeObjectURL(previewUrlRef.current);
previewUrlRef.current = null;
currentPreviewFileRef.current = null;
}
return pdfFile; return pdfFile;
} }
}, [previewFile, pdfFile]); }, [previewFile, pdfFile]);
// Cleanup preview file URL on unmount only
useEffect(() => {
return () => {
if (previewUrlRef.current) {
URL.revokeObjectURL(previewUrlRef.current);
previewUrlRef.current = null;
}
};
}, []);
const scrollAreaRef = useRef<HTMLDivElement>(null); const scrollAreaRef = useRef<HTMLDivElement>(null);
const userInitiatedRef = useRef(false); const userInitiatedRef = useRef(false);
const suppressScrollRef = useRef(false); const suppressScrollRef = useRef(false);
@ -375,9 +340,7 @@ const Viewer = ({
useEffect(() => { useEffect(() => {
let cancelled = false; let cancelled = false;
async function loadPdfInfo() { async function loadPdfInfo() {
console.log('Loading PDF info:', { effectiveFile, previewFile: !!previewFile });
if (!effectiveFile) { if (!effectiveFile) {
console.log('No effective file');
setNumPages(0); setNumPages(0);
setPageImages([]); setPageImages([]);
return; return;
@ -388,15 +351,12 @@ const Viewer = ({
// For preview files, use ArrayBuffer directly to avoid blob URL issues // For preview files, use ArrayBuffer directly to avoid blob URL issues
if (previewFile && effectiveFile.file === previewFile) { if (previewFile && effectiveFile.file === previewFile) {
console.log('Loading preview file as ArrayBuffer');
const arrayBuffer = await previewFile.arrayBuffer(); const arrayBuffer = await previewFile.arrayBuffer();
pdfData = { data: arrayBuffer }; pdfData = { data: arrayBuffer };
console.log('Preview file ArrayBuffer created:', arrayBuffer.byteLength, 'bytes');
} }
// Handle special IndexedDB URLs for large files // Handle special IndexedDB URLs for large files
else if (effectiveFile.url?.startsWith('indexeddb:')) { else if (effectiveFile.url?.startsWith('indexeddb:')) {
const fileId = effectiveFile.url.replace('indexeddb:', ''); const fileId = effectiveFile.url.replace('indexeddb:', '');
console.log('Loading large file from IndexedDB:', fileId);
// Get data directly from IndexedDB // Get data directly from IndexedDB
const arrayBuffer = await fileStorage.getFileData(fileId); const arrayBuffer = await fileStorage.getFileData(fileId);
@ -409,7 +369,6 @@ const Viewer = ({
pdfData = { data: arrayBuffer }; pdfData = { data: arrayBuffer };
} else if (effectiveFile.url) { } else if (effectiveFile.url) {
// Standard blob URL or regular URL // Standard blob URL or regular URL
console.log('Loading PDF from URL:', effectiveFile.url);
pdfData = effectiveFile.url; pdfData = effectiveFile.url;
} else { } else {
throw new Error('No valid PDF source available'); throw new Error('No valid PDF source available');
@ -424,7 +383,6 @@ const Viewer = ({
setTimeout(() => startProgressivePreload(), 100); setTimeout(() => startProgressivePreload(), 100);
} }
} catch (error) { } catch (error) {
console.error('Failed to load PDF:', error);
if (!cancelled) { if (!cancelled) {
setPageImages([]); setPageImages([]);
setNumPages(0); setNumPages(0);

View File

@ -66,7 +66,6 @@ const SplitPdfPanel: React.FC<SplitPdfPanelProps> = ({
thumbnails: [], thumbnails: [],
isGeneratingThumbnails: false isGeneratingThumbnails: false
}); });
const [previewFile, setPreviewFile] = useState<File | null>(null);
const { const {
mode, mode,
@ -87,18 +86,15 @@ const SplitPdfPanel: React.FC<SplitPdfPanelProps> = ({
setDownloadUrl(null); setDownloadUrl(null);
setStatus(""); setStatus("");
} }
// Clear split results and preview file // Clear split results
setSplitResults({ setSplitResults({
files: [], files: [],
thumbnails: [], thumbnails: [],
isGeneratingThumbnails: false isGeneratingThumbnails: false
}); });
setPreviewFile(null);
onPreviewFile?.(null); onPreviewFile?.(null);
// Parameters changed - results will be cleared automatically
}, [mode, pages, hDiv, vDiv, merge, splitType, splitValue, bookmarkLevel, includeMetadata, allowDuplicates, selectedFiles]); }, [mode, pages, hDiv, vDiv, merge, splitType, splitValue, bookmarkLevel, includeMetadata, allowDuplicates, selectedFiles]);
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
if (selectedFiles.length === 0) { if (selectedFiles.length === 0) {
@ -251,14 +247,8 @@ const SplitPdfPanel: React.FC<SplitPdfPanelProps> = ({
// Handle thumbnail click to open in viewer // Handle thumbnail click to open in viewer
const handleThumbnailClick = (file: File) => { const handleThumbnailClick = (file: File) => {
try { try {
// Set as preview file (no context pollution)
setPreviewFile(file);
onPreviewFile?.(file); onPreviewFile?.(file);
// Store that we came from Split tool for return navigation
sessionStorage.setItem('previousMode', 'split'); sessionStorage.setItem('previousMode', 'split');
// Switch to viewer mode
setCurrentMode('viewer'); setCurrentMode('viewer');
} catch (error) { } catch (error) {
console.error('Failed to open file in viewer:', error); console.error('Failed to open file in viewer:', error);
@ -334,9 +324,7 @@ const SplitPdfPanel: React.FC<SplitPdfPanelProps> = ({
setStatus(""); setStatus("");
setErrorMessage(null); setErrorMessage(null);
// Clear any active preview and return to previous view // Clear any active preview and return to previous view
setPreviewFile(null);
onPreviewFile?.(null); onPreviewFile?.(null);
// Return to the Split tool view
setCurrentMode('split'); setCurrentMode('split');
} : undefined} } : undefined}
> >