mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 11:23:10 +02:00
Feature/v2/filemanager (#4121)
FileManager Component Overview
Purpose: Modal component for selecting and managing PDF files with
preview capabilities
Architecture:
- Responsive Layouts: MobileLayout.tsx (stacked) vs DesktopLayout.tsx
(3-column)
- Central State: FileManagerContext handles file operations, selection,
and modal state
- File Storage: IndexedDB persistence with thumbnail caching
Key Components:
- FileSourceButtons: Switch between Recent/Local/Drive sources
- FileListArea: Scrollable file grid with search functionality
- FilePreview: PDF thumbnails with dynamic shadow stacking (1-2 shadow
pages based on file count)
- FileDetails: File info card with metadata
- CompactFileDetails: Mobile-optimized file info layout
File Flow:
1. Users select source → browse/search files → select multiple files →
preview with navigation → open in
tools
2. Files persist across tool switches via FileContext integration
3. Memory management handles large PDFs (up to 100GB+)
```mermaid
graph TD
FM[FileManager] --> ML[MobileLayout]
FM --> DL[DesktopLayout]
ML --> FSB[FileSourceButtons<br/>Recent/Local/Drive]
ML --> FLA[FileListArea]
ML --> FD[FileDetails]
DL --> FSB
DL --> FLA
DL --> FD
FLA --> FLI[FileListItem]
FD --> FP[FilePreview]
FD --> CFD[CompactFileDetails]
```
---------
Co-authored-by: Connor Yoh <[email protected]>
This commit is contained in:
@@ -1,21 +1,58 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { useFilesModal, UseFilesModalReturn } from '../hooks/useFilesModal';
|
||||
import React, { createContext, useContext, useState, useCallback } from 'react';
|
||||
import { useFileHandler } from '../hooks/useFileHandler';
|
||||
|
||||
interface FilesModalContextType extends UseFilesModalReturn {}
|
||||
interface FilesModalContextType {
|
||||
isFilesModalOpen: boolean;
|
||||
openFilesModal: () => void;
|
||||
closeFilesModal: () => void;
|
||||
onFileSelect: (file: File) => void;
|
||||
onFilesSelect: (files: File[]) => void;
|
||||
onModalClose: () => void;
|
||||
setOnModalClose: (callback: () => void) => void;
|
||||
}
|
||||
|
||||
const FilesModalContext = createContext<FilesModalContextType | null>(null);
|
||||
|
||||
export const FilesModalProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const { addToActiveFiles, addMultipleFiles } = useFileHandler();
|
||||
|
||||
const filesModal = useFilesModal({
|
||||
onFileSelect: addToActiveFiles,
|
||||
onFilesSelect: addMultipleFiles,
|
||||
});
|
||||
const [isFilesModalOpen, setIsFilesModalOpen] = useState(false);
|
||||
const [onModalClose, setOnModalClose] = useState<(() => void) | undefined>();
|
||||
|
||||
const openFilesModal = useCallback(() => {
|
||||
setIsFilesModalOpen(true);
|
||||
}, []);
|
||||
|
||||
const closeFilesModal = useCallback(() => {
|
||||
setIsFilesModalOpen(false);
|
||||
onModalClose?.();
|
||||
}, [onModalClose]);
|
||||
|
||||
const handleFileSelect = useCallback((file: File) => {
|
||||
addToActiveFiles(file);
|
||||
closeFilesModal();
|
||||
}, [addToActiveFiles, closeFilesModal]);
|
||||
|
||||
const handleFilesSelect = useCallback((files: File[]) => {
|
||||
addMultipleFiles(files);
|
||||
closeFilesModal();
|
||||
}, [addMultipleFiles, closeFilesModal]);
|
||||
|
||||
const setModalCloseCallback = useCallback((callback: () => void) => {
|
||||
setOnModalClose(() => callback);
|
||||
}, []);
|
||||
|
||||
const contextValue: FilesModalContextType = {
|
||||
isFilesModalOpen,
|
||||
openFilesModal,
|
||||
closeFilesModal,
|
||||
onFileSelect: handleFileSelect,
|
||||
onFilesSelect: handleFilesSelect,
|
||||
onModalClose,
|
||||
setOnModalClose: setModalCloseCallback,
|
||||
};
|
||||
|
||||
return (
|
||||
<FilesModalContext.Provider value={filesModal}>
|
||||
<FilesModalContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</FilesModalContext.Provider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user