Revert some changes in favour of any typing

This commit is contained in:
James 2025-08-08 15:20:51 +01:00
parent 507ad1dc61
commit 5c10586268
2 changed files with 71 additions and 72 deletions

View File

@ -70,11 +70,11 @@ const FileEditor = ({
} = fileContext; } = fileContext;
// Get file selection context // Get file selection context
const { const {
selectedFiles: toolSelectedFiles, selectedFiles: toolSelectedFiles,
setSelectedFiles: setToolSelectedFiles, setSelectedFiles: setToolSelectedFiles,
maxFiles, maxFiles,
isToolMode isToolMode
} = useFileSelection(); } = useFileSelection();
const [files, setFiles] = useState<FileItem[]>([]); const [files, setFiles] = useState<FileItem[]>([]);
@ -82,7 +82,7 @@ const FileEditor = ({
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [localLoading, setLocalLoading] = useState(false); const [localLoading, setLocalLoading] = useState(false);
const [selectionMode, setSelectionMode] = useState(toolMode); const [selectionMode, setSelectionMode] = useState(toolMode);
// Enable selection mode automatically in tool mode // Enable selection mode automatically in tool mode
React.useEffect(() => { React.useEffect(() => {
if (toolMode) { if (toolMode) {
@ -115,7 +115,7 @@ const FileEditor = ({
// Get selected file IDs from context (defensive programming) // Get selected file IDs from context (defensive programming)
const contextSelectedIds = Array.isArray(selectedFileIds) ? selectedFileIds : []; const contextSelectedIds = Array.isArray(selectedFileIds) ? selectedFileIds : [];
// Map context selections to local file IDs for UI display // Map context selections to local file IDs for UI display
const localSelectedIds = files const localSelectedIds = files
.filter(file => { .filter(file => {
@ -144,33 +144,33 @@ const FileEditor = ({
// Check if the actual content has changed, not just references // Check if the actual content has changed, not just references
const currentActiveFileNames = activeFiles.map(f => f.name); const currentActiveFileNames = activeFiles.map(f => f.name);
const currentProcessedFilesSize = processedFiles.size; const currentProcessedFilesSize = processedFiles.size;
const activeFilesChanged = JSON.stringify(currentActiveFileNames) !== JSON.stringify(lastActiveFilesRef.current); const activeFilesChanged = JSON.stringify(currentActiveFileNames) !== JSON.stringify(lastActiveFilesRef.current);
const processedFilesChanged = currentProcessedFilesSize !== lastProcessedFilesRef.current; const processedFilesChanged = currentProcessedFilesSize !== lastProcessedFilesRef.current;
if (!activeFilesChanged && !processedFilesChanged) { if (!activeFilesChanged && !processedFilesChanged) {
return; return;
} }
// Update refs // Update refs
lastActiveFilesRef.current = currentActiveFileNames; lastActiveFilesRef.current = currentActiveFileNames;
lastProcessedFilesRef.current = currentProcessedFilesSize; lastProcessedFilesRef.current = currentProcessedFilesSize;
const convertActiveFiles = async () => { const convertActiveFiles = async () => {
if (activeFiles.length > 0) { if (activeFiles.length > 0) {
setLocalLoading(true); setLocalLoading(true);
try { try {
// Process files in chunks to avoid blocking UI // Process files in chunks to avoid blocking UI
const convertedFiles: FileItem[] = []; const convertedFiles: FileItem[] = [];
for (let i = 0; i < activeFiles.length; i++) { for (let i = 0; i < activeFiles.length; i++) {
const file = activeFiles[i]; const file = activeFiles[i];
// Try to get thumbnail from processed file first // Try to get thumbnail from processed file first
const processedFile = processedFiles.get(file); const processedFile = processedFiles.get(file);
let thumbnail = processedFile?.pages?.[0]?.thumbnail; let thumbnail = processedFile?.pages?.[0]?.thumbnail;
// If no thumbnail from processed file, try to generate one // If no thumbnail from processed file, try to generate one
if (!thumbnail) { if (!thumbnail) {
try { try {
@ -180,7 +180,7 @@ const FileEditor = ({
thumbnail = undefined; // Use placeholder thumbnail = undefined; // Use placeholder
} }
} }
const convertedFile = { const convertedFile = {
id: `file-${Date.now()}-${Math.random()}`, id: `file-${Date.now()}-${Math.random()}`,
name: file.name, name: file.name,
@ -189,19 +189,19 @@ const FileEditor = ({
size: file.size, size: file.size,
file, file,
}; };
convertedFiles.push(convertedFile); convertedFiles.push(convertedFile);
// Update progress // Update progress
setConversionProgress(((i + 1) / activeFiles.length) * 100); setConversionProgress(((i + 1) / activeFiles.length) * 100);
// Yield to main thread between files // Yield to main thread between files
if (i < activeFiles.length - 1) { if (i < activeFiles.length - 1) {
await new Promise(resolve => requestAnimationFrame(resolve)); await new Promise(resolve => requestAnimationFrame(resolve));
} }
} }
setFiles(convertedFiles); setFiles(convertedFiles);
} catch (err) { } catch (err) {
console.error('Error converting active files:', err); console.error('Error converting active files:', err);
@ -237,7 +237,7 @@ const FileEditor = ({
try { try {
// Validate ZIP file first // Validate ZIP file first
const validation = await zipFileService.validateZipFile(file); const validation = await zipFileService.validateZipFile(file);
if (validation.isValid && validation.containsPDFs) { if (validation.isValid && validation.containsPDFs) {
// ZIP contains PDFs - extract them // ZIP contains PDFs - extract them
setZipExtractionProgress({ setZipExtractionProgress({
@ -269,7 +269,7 @@ const FileEditor = ({
if (extractionResult.success) { if (extractionResult.success) {
allExtractedFiles.push(...extractionResult.extractedFiles); allExtractedFiles.push(...extractionResult.extractedFiles);
// Record ZIP extraction operation // Record ZIP extraction operation
const operationId = `zip-extract-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; const operationId = `zip-extract-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
const operation: FileOperation = { const operation: FileOperation = {
@ -289,10 +289,10 @@ const FileEditor = ({
} }
} }
}; };
recordOperation(file.name, operation); recordOperation(file.name, operation);
markOperationApplied(file.name, operationId); markOperationApplied(file.name, operationId);
if (extractionResult.errors.length > 0) { if (extractionResult.errors.length > 0) {
errors.push(...extractionResult.errors); errors.push(...extractionResult.errors);
} }
@ -344,7 +344,7 @@ const FileEditor = ({
} }
} }
}; };
recordOperation(file.name, operation); recordOperation(file.name, operation);
markOperationApplied(file.name, operationId); markOperationApplied(file.name, operationId);
} }
@ -357,7 +357,7 @@ const FileEditor = ({
const errorMessage = err instanceof Error ? err.message : 'Failed to process files'; const errorMessage = err instanceof Error ? err.message : 'Failed to process files';
setError(errorMessage); setError(errorMessage);
console.error('File processing error:', err); console.error('File processing error:', err);
// Reset extraction progress on error // Reset extraction progress on error
setZipExtractionProgress({ setZipExtractionProgress({
isExtracting: false, isExtracting: false,
@ -377,7 +377,7 @@ const FileEditor = ({
const closeAllFiles = useCallback(() => { const closeAllFiles = useCallback(() => {
if (activeFiles.length === 0) return; if (activeFiles.length === 0) return;
// Record close all operation for each file // Record close all operation for each file
activeFiles.forEach(file => { activeFiles.forEach(file => {
const operationId = `close-all-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; const operationId = `close-all-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
@ -396,14 +396,14 @@ const FileEditor = ({
} }
} }
}; };
recordOperation(file.name, operation); recordOperation(file.name, operation);
markOperationApplied(file.name, operationId); markOperationApplied(file.name, operationId);
}); });
// Remove all files from context but keep in storage // Remove all files from context but keep in storage
removeFiles(activeFiles.map(f => (f as any).id || f.name), false); removeFiles(activeFiles.map(f => (f as any).id || f.name), false);
// Clear selections // Clear selections
setContextSelectedFiles([]); setContextSelectedFiles([]);
}, [activeFiles, removeFiles, setContextSelectedFiles, recordOperation, markOperationApplied]); }, [activeFiles, removeFiles, setContextSelectedFiles, recordOperation, markOperationApplied]);
@ -411,12 +411,12 @@ const FileEditor = ({
const toggleFile = useCallback((fileId: string) => { const toggleFile = useCallback((fileId: string) => {
const targetFile = files.find(f => f.id === fileId); const targetFile = files.find(f => f.id === fileId);
if (!targetFile) return; if (!targetFile) return;
const contextFileId = (targetFile.file as any).id || targetFile.name; const contextFileId = (targetFile.file as any).id || targetFile.name;
const isSelected = contextSelectedIds.includes(contextFileId); const isSelected = contextSelectedIds.includes(contextFileId);
let newSelection: string[]; let newSelection: string[];
if (isSelected) { if (isSelected) {
// Remove file from selection // Remove file from selection
newSelection = contextSelectedIds.filter(id => id !== contextFileId); newSelection = contextSelectedIds.filter(id => id !== contextFileId);
@ -433,10 +433,10 @@ const FileEditor = ({
newSelection = [...contextSelectedIds, contextFileId]; newSelection = [...contextSelectedIds, contextFileId];
} }
} }
// Update context // Update context
setContextSelectedFiles(newSelection); setContextSelectedFiles(newSelection);
// Update tool selection context if in tool mode // Update tool selection context if in tool mode
if (isToolMode || toolMode) { if (isToolMode || toolMode) {
const selectedFiles = files const selectedFiles = files
@ -572,12 +572,12 @@ const FileEditor = ({
console.log('handleDeleteFile called with fileId:', fileId); console.log('handleDeleteFile called with fileId:', fileId);
const file = files.find(f => f.id === fileId); const file = files.find(f => f.id === fileId);
console.log('Found file:', file); console.log('Found file:', file);
if (file) { if (file) {
console.log('Attempting to remove file:', file.name); console.log('Attempting to remove file:', file.name);
console.log('Actual file object:', file.file); console.log('Actual file object:', file.file);
console.log('Actual file.file.name:', file.file.name); console.log('Actual file.file.name:', file.file.name);
// Record close operation // Record close operation
const fileName = file.file.name; const fileName = file.file.name;
const fileId = (file.file as any).id || fileName; const fileId = (file.file as any).id || fileName;
@ -597,19 +597,18 @@ const FileEditor = ({
} }
} }
}; };
recordOperation(fileName, operation); recordOperation(fileName, operation);
// Remove file from context but keep in storage (close, don't delete) // Remove file from context but keep in storage (close, don't delete)
console.log('Calling removeFiles with:', [fileId]); console.log('Calling removeFiles with:', [fileId]);
removeFiles([fileId], false); removeFiles([fileId], false);
// Remove from context selections // Remove from context selections
setContextSelectedFiles(prev => { setContextSelectedFiles(prev => {
const safePrev = Array.isArray(prev) ? prev : []; const safePrev = Array.isArray(prev) ? prev : [];
return safePrev.filter(id => id !== fileId); return safePrev.filter(id => id !== fileId);
}); });
// Mark operation as applied // Mark operation as applied
markOperationApplied(fileName, operationId); markOperationApplied(fileName, operationId);
} else { } else {
@ -670,7 +669,7 @@ const FileEditor = ({
accept={["*/*"]} accept={["*/*"]}
multiple={true} multiple={true}
maxSize={2 * 1024 * 1024 * 1024} maxSize={2 * 1024 * 1024 * 1024}
style={{ style={{
height: '100vh', height: '100vh',
border: 'none', border: 'none',
borderRadius: 0, borderRadius: 0,
@ -707,7 +706,7 @@ const FileEditor = ({
) : files.length === 0 && (localLoading || zipExtractionProgress.isExtracting) ? ( ) : files.length === 0 && (localLoading || zipExtractionProgress.isExtracting) ? (
<Box> <Box>
<SkeletonLoader type="controls" /> <SkeletonLoader type="controls" />
{/* ZIP Extraction Progress */} {/* ZIP Extraction Progress */}
{zipExtractionProgress.isExtracting && ( {zipExtractionProgress.isExtracting && (
<Box mb="md" p="sm" style={{ backgroundColor: 'var(--mantine-color-orange-0)', borderRadius: 8 }}> <Box mb="md" p="sm" style={{ backgroundColor: 'var(--mantine-color-orange-0)', borderRadius: 8 }}>
@ -721,10 +720,10 @@ const FileEditor = ({
<Text size="xs" c="dimmed" mb="xs"> <Text size="xs" c="dimmed" mb="xs">
{zipExtractionProgress.extractedCount} of {zipExtractionProgress.totalFiles} files extracted {zipExtractionProgress.extractedCount} of {zipExtractionProgress.totalFiles} files extracted
</Text> </Text>
<div style={{ <div style={{
width: '100%', width: '100%',
height: '4px', height: '4px',
backgroundColor: 'var(--mantine-color-gray-2)', backgroundColor: 'var(--mantine-color-gray-2)',
borderRadius: '2px', borderRadius: '2px',
overflow: 'hidden' overflow: 'hidden'
}}> }}>
@ -737,7 +736,7 @@ const FileEditor = ({
</div> </div>
</Box> </Box>
)} )}
{/* Processing indicator */} {/* Processing indicator */}
{localLoading && ( {localLoading && (
<Box mb="md" p="sm" style={{ backgroundColor: 'var(--mantine-color-blue-0)', borderRadius: 8 }}> <Box mb="md" p="sm" style={{ backgroundColor: 'var(--mantine-color-blue-0)', borderRadius: 8 }}>
@ -745,10 +744,10 @@ const FileEditor = ({
<Text size="sm" fw={500}>Loading files...</Text> <Text size="sm" fw={500}>Loading files...</Text>
<Text size="sm" c="dimmed">{Math.round(conversionProgress)}%</Text> <Text size="sm" c="dimmed">{Math.round(conversionProgress)}%</Text>
</Group> </Group>
<div style={{ <div style={{
width: '100%', width: '100%',
height: '4px', height: '4px',
backgroundColor: 'var(--mantine-color-gray-2)', backgroundColor: 'var(--mantine-color-gray-2)',
borderRadius: '2px', borderRadius: '2px',
overflow: 'hidden' overflow: 'hidden'
}}> }}>
@ -761,27 +760,27 @@ const FileEditor = ({
</div> </div>
</Box> </Box>
)} )}
<SkeletonLoader type="fileGrid" count={6} /> <SkeletonLoader type="fileGrid" count={6} />
</Box> </Box>
) : ( ) : (
<DragDropGrid <DragDropGrid
items={files} items={files}
selectedItems={localSelectedIds} selectedItems={localSelectedIds as any /* FIX ME */}
selectionMode={selectionMode} selectionMode={selectionMode}
isAnimating={isAnimating} isAnimating={isAnimating}
onDragStart={handleDragStart} onDragStart={handleDragStart as any /* FIX ME */}
onDragEnd={handleDragEnd} onDragEnd={handleDragEnd}
onDragOver={handleDragOver} onDragOver={handleDragOver}
onDragEnter={handleDragEnter} onDragEnter={handleDragEnter as any /* FIX ME */}
onDragLeave={handleDragLeave} onDragLeave={handleDragLeave}
onDrop={handleDrop} onDrop={handleDrop as any /* FIX ME */}
onEndZoneDragEnter={handleEndZoneDragEnter} onEndZoneDragEnter={handleEndZoneDragEnter}
draggedItem={draggedFile} draggedItem={draggedFile as any /* FIX ME */}
dropTarget={dropTarget} dropTarget={dropTarget as any /* FIX ME */}
multiItemDrag={multiFileDrag} multiItemDrag={multiFileDrag as any /* FIX ME */}
dragPosition={dragPosition} dragPosition={dragPosition}
renderItem={(file, index, refs) => ( renderItem={(file, index, refs) => (
<FileThumbnail <FileThumbnail
file={file} file={file}
index={index} index={index}

View File

@ -29,7 +29,7 @@ interface PageThumbnailProps {
selectedPages: number[]; selectedPages: number[];
selectionMode: boolean; selectionMode: boolean;
draggedPage: number | null; draggedPage: number | null;
dropTarget: number | null; dropTarget: number | 'end' | null;
movingPage: number | null; movingPage: number | null;
isAnimating: boolean; isAnimating: boolean;
pageRefs: React.MutableRefObject<Map<string, HTMLDivElement>>; pageRefs: React.MutableRefObject<Map<string, HTMLDivElement>>;
@ -82,7 +82,7 @@ const PageThumbnail = React.memo(({
}: PageThumbnailProps) => { }: PageThumbnailProps) => {
const [thumbnailUrl, setThumbnailUrl] = useState<string | null>(page.thumbnail); const [thumbnailUrl, setThumbnailUrl] = useState<string | null>(page.thumbnail);
const [isLoadingThumbnail, setIsLoadingThumbnail] = useState(false); const [isLoadingThumbnail, setIsLoadingThumbnail] = useState(false);
// Update thumbnail URL when page prop changes // Update thumbnail URL when page prop changes
useEffect(() => { useEffect(() => {
if (page.thumbnail && page.thumbnail !== thumbnailUrl) { if (page.thumbnail && page.thumbnail !== thumbnailUrl) {
@ -97,13 +97,13 @@ const PageThumbnail = React.memo(({
console.log(`📸 PageThumbnail: Page ${page.pageNumber} already has thumbnail, skipping worker listener`); console.log(`📸 PageThumbnail: Page ${page.pageNumber} already has thumbnail, skipping worker listener`);
return; // Skip if we already have a thumbnail return; // Skip if we already have a thumbnail
} }
console.log(`📸 PageThumbnail: Setting up worker listener for page ${page.pageNumber} (${page.id})`); console.log(`📸 PageThumbnail: Setting up worker listener for page ${page.pageNumber} (${page.id})`);
const handleThumbnailReady = (event: CustomEvent) => { const handleThumbnailReady = (event: CustomEvent) => {
const { pageNumber, thumbnail, pageId } = event.detail; const { pageNumber, thumbnail, pageId } = event.detail;
console.log(`📸 PageThumbnail: Received worker thumbnail for page ${pageNumber}, looking for page ${page.pageNumber} (${page.id})`); console.log(`📸 PageThumbnail: Received worker thumbnail for page ${pageNumber}, looking for page ${page.pageNumber} (${page.id})`);
if (pageNumber === page.pageNumber && pageId === page.id) { if (pageNumber === page.pageNumber && pageId === page.id) {
console.log(`✓ PageThumbnail: Thumbnail matched for page ${page.pageNumber}, setting URL`); console.log(`✓ PageThumbnail: Thumbnail matched for page ${page.pageNumber}, setting URL`);
setThumbnailUrl(thumbnail); setThumbnailUrl(thumbnail);