160 lines
4.3 KiB
TypeScript
160 lines
4.3 KiB
TypeScript
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
import type { SplitResult } from '../pdf/pdfTypes';
|
|
|
|
export interface PdfDownload {
|
|
id: string;
|
|
filename: string;
|
|
url: string;
|
|
}
|
|
|
|
export interface SplitPdfDownload extends PdfDownload {
|
|
pageIndex: number;
|
|
}
|
|
|
|
export interface PdfBlobResult {
|
|
blob: Blob;
|
|
filename: string;
|
|
}
|
|
|
|
function revokeDownload(download: PdfDownload | null): void {
|
|
if (download) {
|
|
URL.revokeObjectURL(download.url);
|
|
}
|
|
}
|
|
|
|
function revokeDownloads(downloads: PdfDownload[]): void {
|
|
downloads.forEach(revokeDownload);
|
|
}
|
|
|
|
function createDownload(id: string, filename: string, blob: Blob): PdfDownload {
|
|
return {
|
|
id,
|
|
filename,
|
|
url: URL.createObjectURL(blob),
|
|
};
|
|
}
|
|
|
|
export function usePdfGeneratedOutputs() {
|
|
const [splitDownloads, setSplitDownloads] = useState<SplitPdfDownload[]>([]);
|
|
const [subsetDownload, setSubsetDownload] = useState<PdfDownload | null>(
|
|
null
|
|
);
|
|
const [exportDownload, setExportDownload] = useState<PdfDownload | null>(
|
|
null
|
|
);
|
|
const [splitZipDownload, setSplitZipDownload] = useState<PdfDownload | null>(
|
|
null
|
|
);
|
|
|
|
const splitDownloadsRef = useRef<SplitPdfDownload[]>([]);
|
|
const subsetDownloadRef = useRef<PdfDownload | null>(null);
|
|
const exportDownloadRef = useRef<PdfDownload | null>(null);
|
|
const splitZipDownloadRef = useRef<PdfDownload | null>(null);
|
|
|
|
const replaceSplitResults = useCallback(
|
|
(results: SplitResult[], zipResult?: PdfBlobResult) => {
|
|
const nextDownloads: SplitPdfDownload[] = results.map((result) => ({
|
|
...createDownload(
|
|
`split-${result.pageIndex}-${result.filename}`,
|
|
result.filename,
|
|
result.blob
|
|
),
|
|
pageIndex: result.pageIndex,
|
|
}));
|
|
|
|
const nextZipDownload = zipResult
|
|
? createDownload('split-zip', zipResult.filename, zipResult.blob)
|
|
: null;
|
|
|
|
revokeDownloads(splitDownloadsRef.current);
|
|
revokeDownload(splitZipDownloadRef.current);
|
|
|
|
splitDownloadsRef.current = nextDownloads;
|
|
splitZipDownloadRef.current = nextZipDownload;
|
|
|
|
setSplitDownloads(nextDownloads);
|
|
setSplitZipDownload(nextZipDownload);
|
|
},
|
|
[]
|
|
);
|
|
|
|
const clearSplitResults = useCallback(() => {
|
|
revokeDownloads(splitDownloadsRef.current);
|
|
revokeDownload(splitZipDownloadRef.current);
|
|
|
|
splitDownloadsRef.current = [];
|
|
splitZipDownloadRef.current = null;
|
|
|
|
setSplitDownloads([]);
|
|
setSplitZipDownload(null);
|
|
}, []);
|
|
|
|
const replaceSubsetResult = useCallback((blob: Blob, filename: string) => {
|
|
const nextDownload = createDownload('subset', filename, blob);
|
|
|
|
revokeDownload(subsetDownloadRef.current);
|
|
subsetDownloadRef.current = nextDownload;
|
|
setSubsetDownload(nextDownload);
|
|
}, []);
|
|
|
|
const clearSubsetResult = useCallback(() => {
|
|
revokeDownload(subsetDownloadRef.current);
|
|
subsetDownloadRef.current = null;
|
|
setSubsetDownload(null);
|
|
}, []);
|
|
|
|
const replaceExportResult = useCallback((blob: Blob, filename: string) => {
|
|
const nextDownload = createDownload('export', filename, blob);
|
|
|
|
revokeDownload(exportDownloadRef.current);
|
|
exportDownloadRef.current = nextDownload;
|
|
setExportDownload(nextDownload);
|
|
}, []);
|
|
|
|
const clearExportResult = useCallback(() => {
|
|
revokeDownload(exportDownloadRef.current);
|
|
exportDownloadRef.current = null;
|
|
setExportDownload(null);
|
|
}, []);
|
|
|
|
const clearAllResults = useCallback(() => {
|
|
revokeDownloads(splitDownloadsRef.current);
|
|
revokeDownload(subsetDownloadRef.current);
|
|
revokeDownload(exportDownloadRef.current);
|
|
revokeDownload(splitZipDownloadRef.current);
|
|
|
|
splitDownloadsRef.current = [];
|
|
subsetDownloadRef.current = null;
|
|
exportDownloadRef.current = null;
|
|
splitZipDownloadRef.current = null;
|
|
|
|
setSplitDownloads([]);
|
|
setSubsetDownload(null);
|
|
setExportDownload(null);
|
|
setSplitZipDownload(null);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
revokeDownloads(splitDownloadsRef.current);
|
|
revokeDownload(subsetDownloadRef.current);
|
|
revokeDownload(exportDownloadRef.current);
|
|
revokeDownload(splitZipDownloadRef.current);
|
|
};
|
|
}, []);
|
|
|
|
return {
|
|
splitDownloads,
|
|
subsetDownload,
|
|
exportDownload,
|
|
splitZipDownload,
|
|
replaceSplitResults,
|
|
clearSplitResults,
|
|
replaceSubsetResult,
|
|
clearSubsetResult,
|
|
replaceExportResult,
|
|
clearExportResult,
|
|
clearAllResults,
|
|
};
|
|
}
|