diff --git a/frontend/src/contexts/FilesModalContext.tsx b/frontend/src/contexts/FilesModalContext.tsx index 703c8b05c..e850fa4dd 100644 --- a/frontend/src/contexts/FilesModalContext.tsx +++ b/frontend/src/contexts/FilesModalContext.tsx @@ -2,6 +2,7 @@ import React, { createContext, useContext, useState, useCallback, useMemo } from import { useFileHandler } from '../hooks/useFileHandler'; import { useFileActions } from './FileContext'; import { StirlingFileStub } from '../types/fileContext'; +import { fileStorage } from '../services/fileStorage'; interface FilesModalContextType { isFilesModalOpen: boolean; @@ -47,23 +48,34 @@ export const FilesModalProvider: React.FC<{ children: React.ReactNode }> = ({ ch closeFilesModal(); }, [addFiles, closeFilesModal, insertAfterPage, customHandler]); - const handleRecentFileSelect = useCallback((stirlingFileStubs: StirlingFileStub[]) => { + const handleRecentFileSelect = useCallback(async (stirlingFileStubs: StirlingFileStub[]) => { if (customHandler) { - // For custom handlers, we need to load the actual files first - // This is a bit complex - for now, let's not support custom handlers with stubs - console.warn('Custom handlers not yet supported for StirlingFileStub selection'); - closeFilesModal(); - return; - } - - // Use the new addStirlingFileStubs action to preserve metadata - if (actions.addStirlingFileStubs) { - actions.addStirlingFileStubs(stirlingFileStubs, { selectFiles: true }); + // Load the actual files from storage for custom handler + try { + const loadedFiles: File[] = []; + for (const stub of stirlingFileStubs) { + const stirlingFile = await fileStorage.getStirlingFile(stub.id); + if (stirlingFile) { + loadedFiles.push(stirlingFile); + } + } + + if (loadedFiles.length > 0) { + customHandler(loadedFiles, insertAfterPage); + } + } catch (error) { + console.error('Failed to load files for custom handler:', error); + } } else { - console.error('addStirlingFileStubs action not available'); + // Normal case - use addStirlingFileStubs to preserve metadata + if (actions.addStirlingFileStubs) { + actions.addStirlingFileStubs(stirlingFileStubs, { selectFiles: true }); + } else { + console.error('addStirlingFileStubs action not available'); + } } closeFilesModal(); - }, [actions.addStirlingFileStubs, closeFilesModal, customHandler]); + }, [actions.addStirlingFileStubs, closeFilesModal, customHandler, insertAfterPage]); const setModalCloseCallback = useCallback((callback: () => void) => { setOnModalClose(() => callback); diff --git a/frontend/src/contexts/file/fileActions.ts b/frontend/src/contexts/file/fileActions.ts index cd61f42e7..de5c32370 100644 --- a/frontend/src/contexts/file/fileActions.ts +++ b/frontend/src/contexts/file/fileActions.ts @@ -545,6 +545,31 @@ export async function addStirlingFileStubs( record.insertAfterPageId = options.insertAfterPageId; } + // Check if processedFile data needs regeneration for proper Page Editor support + if (stirlingFile.type.startsWith('application/pdf')) { + const needsProcessing = !record.processedFile || + !record.processedFile.pages || + record.processedFile.pages.length === 0 || + record.processedFile.totalPages !== record.processedFile.pages.length; + + if (needsProcessing) { + if (DEBUG) console.log(`📄 addStirlingFileStubs: Regenerating processedFile for ${record.name}`); + try { + // Generate basic processedFile structure with page count + const result = await generateThumbnailWithMetadata(stirlingFile); + record.processedFile = createProcessedFile(result.pageCount, result.thumbnail); + record.thumbnailUrl = result.thumbnail; // Update thumbnail if needed + if (DEBUG) console.log(`📄 addStirlingFileStubs: Regenerated processedFile for ${record.name} with ${result.pageCount} pages`); + } catch (error) { + if (DEBUG) console.warn(`📄 addStirlingFileStubs: Failed to regenerate processedFile for ${record.name}:`, error); + // Ensure we have at least basic structure + if (!record.processedFile) { + record.processedFile = createProcessedFile(1); // Fallback to 1 page + } + } + } + } + existingQuickKeys.add(stub.quickKey || ''); validStubs.push(record); loadedFiles.push(stirlingFile); diff --git a/frontend/src/hooks/useFileHandler.ts b/frontend/src/hooks/useFileHandler.ts index 5996b75fe..c29b5bd36 100644 --- a/frontend/src/hooks/useFileHandler.ts +++ b/frontend/src/hooks/useFileHandler.ts @@ -4,9 +4,11 @@ import { useFileActions } from '../contexts/FileContext'; export const useFileHandler = () => { const { actions } = useFileActions(); - const addFiles = useCallback(async (files: File[]) => { + const addFiles = useCallback(async (files: File[], options: { insertAfterPageId?: string; selectFiles?: boolean } = {}) => { + // Merge default options with passed options - passed options take precedence + const mergedOptions = { selectFiles: true, ...options }; // Let FileContext handle deduplication with quickKey logic - await actions.addFiles(files, { selectFiles: true }); + await actions.addFiles(files, mergedOptions); }, [actions.addFiles]); return {