[REFACTOR] Change upload and download architecture#345
Conversation
- Implemented S3 storage integration, replacing the previous filesystem storage. - Added automatic migration script for existing files from filesystem to S3. - Updated Docker configuration to include MinIO for local S3 emulation. - Removed obsolete filesystem-related code and endpoints. - Enhanced upload and download functionalities to utilize presigned URLs for S3. - Updated environment configuration to support S3 settings. This change significantly simplifies file management and enhances scalability.
…d UI improvements - Introduced a new `useDragDrop` hook to manage drag-and-drop operations for files and folders. - Updated `FilesGrid` and `FilesViewManager` components to support drag-and-drop interactions. - Added immediate update handling for file and folder movements. - Improved user experience with visual feedback during drag-and-drop actions. - Refactored file access logging to enhance security by omitting sensitive information. - Adjusted S3 client configuration and timeout settings for better performance. These changes streamline file operations and enhance the overall user interface.
…states - Added a context menu for file and folder actions, including options to create new folders and upload files. - Implemented skeleton loading components for files grid and table views to improve user experience during data loading. - Updated file and folder components to support new context menu interactions. - Refactored drag-and-drop functionality to integrate with the new context menu features. These changes improve the usability and responsiveness of the file management interface.
- Replaced custom file upload logic with Uppy for improved handling of uploads. - Introduced a new hook `useUppyUpload` to manage file uploads, including multipart support for large files. - Created a centralized upload configuration file to manage upload settings. - Updated `UploadFileModal` component to utilize the new Uppy hook and configuration. - Removed obsolete S3 upload utility as functionality is now handled by Uppy. - Added new API endpoints for multipart upload operations: create, complete, and abort. - Enhanced error handling and user feedback during the upload process.
…nt messages - Updated translation files for multiple languages (ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, ru-RU, tr-TR, zh-CN) to include new keys for authentication success and failure messages, item selection prompts, and error messages related to file operations. - Enhanced user feedback in the UI by integrating translation functions in various components, ensuring that users receive localized messages for actions like moving items, creating shares, and managing files. - Improved accessibility by providing translated titles and descriptions for buttons and dialogs.
- Removed unused translation keys from zh-CN.json. - Added a new script to prune extra translation keys based on the reference file. - Updated package.json to include the new prune script. - Enhanced language switcher to support additional languages: Thai, Vietnamese, Ukrainian, Persian, Swedish, Indonesian, Greek, and Hebrew. - Updated request.ts to include new languages in the supported locales. - Adjusted RTL languages to include Hebrew and Persian.
- Added DTOs for invite token creation, validation, and user registration. - Implemented routes for generating invite tokens, validating tokens, and registering users with invite tokens. - Created InviteService to handle business logic for invite token management. - Integrated invite functionality into the server and web applications. - Added UI components for generating invite links and registering with invites. - Updated translations for invite-related messages in English and Portuguese. - Introduced API endpoints for invite token operations. - Enhanced user management UI to include invite link generation.
… languages - Implemented invitation link generation feature with corresponding messages in Italian, Japanese, Korean, Dutch, Polish, Russian, Swedish, Thai, Turkish, Ukrainian, Vietnamese, and Chinese. - Added user registration form labels, validation messages, and success/error notifications for account creation. - Updated context menus and validation messages to enhance user experience across supported languages.
There was a problem hiding this comment.
Pull request overview
This PR refactors the upload and download architecture to improve performance and reliability. The changes primarily focus on removing the download queue system, implementing a new Uppy-based upload system, and adding drag-and-drop functionality for file management.
Key Changes:
- Replaced custom chunked upload with Uppy library for multipart uploads
- Removed download queue system in favor of direct downloads with caching
- Added drag-and-drop functionality for moving files and folders
- Implemented optimistic UI updates for better user experience
Reviewed changes
Copilot reviewed 91 out of 116 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/web/src/hooks/use-enhanced-file-manager.ts | Removed download queue dependencies and simplified download handling |
| apps/web/src/hooks/use-drag-drop.ts | New hook implementing drag-and-drop functionality for file/folder movement |
| apps/web/src/hooks/use-download-queue.ts | Deleted file - download queue system removed |
| apps/web/src/config/upload-config.ts | New centralized upload configuration file |
| apps/web/src/components/ui/context-menu.tsx | Added context menu UI component for right-click actions |
| apps/web/src/components/modals/upload-file-modal.tsx | Refactored to use new Uppy-based upload system |
| apps/web/src/components/general/global-drop-zone.tsx | Updated to use Uppy hooks instead of custom upload logic |
| apps/web/src/components/tables/files-grid.tsx | Added drag-and-drop support and context menu integration |
| apps/web/src/app/files/page.tsx | Integrated drag-and-drop for breadcrumb navigation and folder downloads |
| apps/web/src/app/files/hooks/use-file-browser.ts | Added optimistic update handler for immediate UI feedback |
| apps/web/package.json | Added Uppy dependencies and new translation script |
| apps/server/src/types/storage.ts | Added multipart upload interface methods |
apps/web/src/hooks/use-drag-drop.ts
Outdated
| handleDragEnd(); | ||
| } | ||
| }, | ||
| [moveFile, moveFolder, onImmediateUpdate, t, onRefresh, handleDragEnd] |
There was a problem hiding this comment.
The dependencies array references moveFile and moveFolder directly, but these are imported functions, not from the component scope. This will cause the handleDrop callback to be recreated on every render because the functions are not memoized, leading to potential performance issues and stale closure bugs.
| [moveFile, moveFolder, onImmediateUpdate, t, onRefresh, handleDragEnd] | |
| [onImmediateUpdate, t, onRefresh, handleDragEnd] |
| // IMPORTANT: Use the objectName returned by backend, not the one we generated! | ||
| // The backend generates: userId/timestamp-random-filename.extension | ||
| const actualObjectName = response.data.objectName; |
There was a problem hiding this comment.
[nitpick] The comment states to use the backend's objectName, but then the variable is named actualObjectName and immediately returned. Consider either returning response.data.objectName directly or renaming the variable to better indicate why this distinction matters (e.g., backendObjectName).
| if (item.type === "folder" && item.id === target.id) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Lines 193-195 and 197-199 contain duplicate logic checking if item.id === target.id. The second check on line 197 will never be reached because the first check would have already returned false. Remove the redundant folder-specific check.
| if (item.type === "folder" && item.id === target.id) { | |
| return false; | |
| } | |
| // (Redundant check removed) | |
| // | |
| // |
| setTimeout(() => { | ||
| onSuccess?.(); |
There was a problem hiding this comment.
The hardcoded 300ms delay is a magic number without explanation. Add a comment explaining why this delay is necessary (e.g., "Delay to ensure backend has processed all files before refreshing") or extract it to a named constant.
| // Use requestAnimationFrame for smoother updates | ||
| requestAnimationFrame(() => { | ||
| // Check if this is a delete operation | ||
| const isDelete = newParentId === ("__DELETE__" as any); |
There was a problem hiding this comment.
Using the magic string "DELETE" with a type assertion is fragile and error-prone. Consider defining this as a constant (e.g., const DELETE_MARKER = "__DELETE__" as const) or using a more type-safe approach like a discriminated union.
| // Check if this is a move operation (dragging existing items) | ||
| const isMoveOperation = event.dataTransfer?.types.includes("application/x-move-item"); | ||
| if (isMoveOperation) { | ||
| return; // Don't interfere with move operations |
There was a problem hiding this comment.
The logic to detect move operations is duplicated across handleDragOver, handleDragLeave, and handleDrop. Consider extracting this into a helper function to reduce duplication and ensure consistency.
- Changed documentation links from "/docs/3.2-beta" to "/docs/v3-beta" across multiple files. - Updated version display from "v3.2-beta" to "v3-beta" in the Hero component. - Removed deprecated VersionWarning component and related logic. - Introduced V3BetaModal to inform users of important changes in v3.3.0-beta. - Updated API search route to reflect new version tagging. - Adjusted constants for latest version path and version number. - Updated package versions for server and web applications to "3.3.0-beta". - Cleaned up unused Docker Compose files related to previous versions.
No description provided.