Refactor thumbnail generation

This commit is contained in:
James Brunton 2025-08-15 17:32:00 +01:00
parent 17650bdc95
commit 511328138a

View File

@ -273,6 +273,29 @@ function formatFileSize(bytes: number): string {
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
} }
async function generatePDFThumbnail(arrayBuffer: ArrayBuffer, file: File, scale: number): Promise<string> {
try {
const pdf = await getDocument({
data: arrayBuffer,
disableAutoFetch: true,
disableStream: true
}).promise;
const thumbnail = await generateStandardPDFThumbnail(pdf, scale);
// Immediately clean up memory after thumbnail generation
pdf.destroy();
return thumbnail;
} catch (error) {
if (error instanceof Error) {
// Check if PDF is encrypted
if (error.name === "PasswordException") {
return generateEncryptedPDFThumbnail(file);
}
}
throw error; // Not an encryption issue, re-throw
}
}
/** /**
* Generate thumbnail for any file type * Generate thumbnail for any file type
@ -306,51 +329,15 @@ export async function generateThumbnailForFile(file: File): Promise<string | und
const chunk = file.slice(0, Math.min(chunkSize, file.size)); const chunk = file.slice(0, Math.min(chunkSize, file.size));
const arrayBuffer = await chunk.arrayBuffer(); const arrayBuffer = await chunk.arrayBuffer();
let thumbnail: string;
try { try {
const pdf = await getDocument({ return await generatePDFThumbnail(arrayBuffer, file, scale);
data: arrayBuffer,
disableAutoFetch: true,
disableStream: true
}).promise;
thumbnail = await generateStandardPDFThumbnail(pdf, scale);
// Immediately clean up memory after thumbnail generation
pdf.destroy();
} catch (error) { } catch (error) {
if (error instanceof Error) { if (error instanceof Error) {
// Check if PDF is encrypted if (error.name === 'InvalidPDFException') {
if (error.name === "PasswordException") {
thumbnail = generateEncryptedPDFThumbnail(file);
} else if (error.name === 'InvalidPDFException') {
console.warn(`PDF structure issue for ${file.name} - using fallback thumbnail`); console.warn(`PDF structure issue for ${file.name} - using fallback thumbnail`);
// Return a placeholder or try with full file instead of chunk // Return a placeholder or try with full file instead of chunk
const fullArrayBuffer = await file.arrayBuffer(); const fullArrayBuffer = await file.arrayBuffer();
try { return await generatePDFThumbnail(fullArrayBuffer, file, scale);
const pdf = await getDocument({
data: fullArrayBuffer,
disableAutoFetch: true,
disableStream: true,
verbosity: 0 // Reduce PDF.js warnings
}).promise;
thumbnail = await generateStandardPDFThumbnail(pdf, scale);
pdf.destroy();
} catch (fallbackError) {
if (fallbackError instanceof Error) {
// Check if PDF is encrypted
if (fallbackError.name === "PasswordException") {
thumbnail = generateEncryptedPDFThumbnail(file);
} else {
console.warn('Fallback thumbnail generation also failed for', file.name, fallbackError);
return undefined;
}
} else {
throw fallbackError; // Re-throw non-Error exceptions
}
}
} else { } else {
console.warn('Unknown error thrown. Failed to generate thumbnail for', file.name, error); console.warn('Unknown error thrown. Failed to generate thumbnail for', file.name, error);
return undefined; return undefined;
@ -359,6 +346,4 @@ export async function generateThumbnailForFile(file: File): Promise<string | und
throw error; // Re-throw non-Error exceptions throw error; // Re-throw non-Error exceptions
} }
} }
return thumbnail;
} }