103 lines
2.6 KiB
TypeScript
103 lines
2.6 KiB
TypeScript
import { useCallback, useState } from 'react';
|
|
import { loadPdfFromFile } from '../pdf/pdfService';
|
|
import {
|
|
canMergeQueue,
|
|
createMergeQueueItemId,
|
|
getReadyMergeQueuePdfs,
|
|
hasMergeQueueErrors,
|
|
isMergeQueueLoading,
|
|
moveMergeQueueItem,
|
|
} from './mergeQueueHelpers';
|
|
import type { MergeQueueItem } from './mergeTypes';
|
|
|
|
export function useMergeQueue() {
|
|
const [items, setItems] = useState<MergeQueueItem[]>([]);
|
|
|
|
const addFiles = useCallback((files: File[]) => {
|
|
const pdfFiles = files.filter(
|
|
(file) =>
|
|
file.type === 'application/pdf' ||
|
|
file.name.toLowerCase().endsWith('.pdf')
|
|
);
|
|
|
|
if (pdfFiles.length === 0) return;
|
|
|
|
const queuedItems: MergeQueueItem[] = pdfFiles.map((file) => ({
|
|
id: createMergeQueueItemId(),
|
|
file,
|
|
name: file.name,
|
|
size: file.size,
|
|
pageCount: null,
|
|
pdf: null,
|
|
status: 'loading',
|
|
}));
|
|
|
|
setItems((current) => [...current, ...queuedItems]);
|
|
|
|
queuedItems.forEach((item) => {
|
|
void (async () => {
|
|
try {
|
|
const loadedPdf = await loadPdfFromFile(item.file);
|
|
|
|
setItems((current) =>
|
|
current.map((currentItem) =>
|
|
currentItem.id === item.id
|
|
? {
|
|
...currentItem,
|
|
pdf: loadedPdf,
|
|
pageCount: loadedPdf.pageCount,
|
|
status: 'ready',
|
|
error: undefined,
|
|
}
|
|
: currentItem
|
|
)
|
|
);
|
|
} catch (error) {
|
|
console.error(error);
|
|
|
|
setItems((current) =>
|
|
current.map((currentItem) =>
|
|
currentItem.id === item.id
|
|
? {
|
|
...currentItem,
|
|
status: 'error',
|
|
error: 'Could not load this PDF.',
|
|
}
|
|
: currentItem
|
|
)
|
|
);
|
|
}
|
|
})();
|
|
});
|
|
}, []);
|
|
|
|
const removeItem = useCallback((itemId: string) => {
|
|
setItems((current) => current.filter((item) => item.id !== itemId));
|
|
}, []);
|
|
|
|
const moveItemUp = useCallback((itemId: string) => {
|
|
setItems((current) => moveMergeQueueItem(current, itemId, 'up'));
|
|
}, []);
|
|
|
|
const moveItemDown = useCallback((itemId: string) => {
|
|
setItems((current) => moveMergeQueueItem(current, itemId, 'down'));
|
|
}, []);
|
|
|
|
const clearQueue = useCallback(() => {
|
|
setItems([]);
|
|
}, []);
|
|
|
|
return {
|
|
items,
|
|
addFiles,
|
|
removeItem,
|
|
moveItemUp,
|
|
moveItemDown,
|
|
clearQueue,
|
|
readyPdfs: getReadyMergeQueuePdfs(items),
|
|
canMerge: canMergeQueue(items),
|
|
hasErrors: hasMergeQueueErrors(items),
|
|
isLoading: isMergeQueueLoading(items),
|
|
};
|
|
}
|