Skip to content

feat: Add upload permission field to shared links and file upload interface#11

Merged
Asion001 merged 13 commits intomainfrom
copilot/add-upload-functionality
Nov 12, 2025
Merged

feat: Add upload permission field to shared links and file upload interface#11
Asion001 merged 13 commits intomainfrom
copilot/add-upload-functionality

Conversation

Copy link
Contributor

Copilot AI commented Nov 12, 2025

Upload Functionality Implementation - Complete

Summary

Implemented complete file upload functionality with progress tracking, public link uploads, folder sharing capabilities, proper model-based responses, and polished public shared folder UI.

✅ All Features Completed

Backend Changes

  • Added canUpload boolean field to SharedLink model (default: false)
  • Created database migration (20251112134929406) to add canUpload column
  • Updated LinksEndpoint.create() and update() to handle canUpload parameter
  • Added FileUploadRoute to handle authenticated multipart file uploads
  • Added PublicUploadRoute for public uploads via shared links
  • Added listPublic endpoint to list files in publicly shared folders
  • Added getPublicLinkInfo endpoint for link metadata without auth
  • Implemented proper folder access validation (same as files_endpoint)
  • Created UploadResult model for upload responses
  • Use UploadResult instead of Map for type-safe responses
  • Validate canUpload flag and expiration for public uploads
  • Public uploads only work for folders with canUpload=true

Client Protocol

  • Updated client SharedLink model with canUpload field
  • Updated client endpoint calls to pass canUpload parameter
  • Added UploadResult model to client protocol
  • Ensured proper serialization/deserialization

Flutter UI - Upload Interface

  • Created FileUploadController to manage upload state and progress
  • Implemented file picker integration with file_picker package v10.3.6
  • Created UploadProgressDialog showing upload progress (instance method with builder)
  • Added upload button to files bar
  • Implemented active upload badge with count
  • Real-time progress tracking with percentage and bytes uploaded
  • Upload cancellation functionality
  • Automatic file list refresh after upload
  • Success/failure notifications
  • Created PublicSharedFolderScreen for public link file listing
  • Added route at /public-shared-folder with linkPrefix query parameter
  • Reused FileTile component for consistent file display
  • Added proper translations for all UI text
  • Implemented tap handlers for file/folder interaction

Share Link UI

  • Added canUpload checkbox to CreateShareLinkDialog (only for directories)
  • Added canUpload checkbox to EditShareLinkDialog
  • Updated ShareLinksController to handle canUpload in create and updateLink methods

Localization

  • Added comprehensive upload-related localization strings
  • Added upload button tooltips and progress messages
  • Added "No files in this folder" translation

🎨 UI Features

Upload Button: Click the upload icon in the files bar to select and upload files
Progress Badge: Shows active upload count when uploads are in progress
Progress Dialog: Click the badge to view detailed progress of all uploads
Real-time Updates: Progress bars and percentages update in real-time
Cancellation: Cancel individual uploads with the X button
Status Icons: Visual indicators for pending, uploading, completed, failed, and cancelled states
Public Shared Folder Screen: View files in publicly shared folders via link prefix
Consistent UI: Reuses FileTile component for uniform file display across the app
Error Handling: Shows clear error messages if link is invalid or expired

🔧 Technical Implementation

FileUploadController:

  • Manages upload queue with multiple concurrent uploads
  • Tracks progress, status, and errors for each file
  • Supports cancellation via Dio CancelToken
  • Notifies UI of state changes via ChangeNotifier
  • Automatically refreshes file list after successful uploads

FileUploadRoute (Authenticated):

  • Handles multipart/form-data POST requests at /upload
  • Validates authentication using Serverpod auth
  • Proper folder access validation matching files_endpoint
  • Supports uploads to authenticated user's accessible folders
  • Creates directories recursively if needed
  • Returns UploadResult model for type-safe response

PublicUploadRoute (Public Links):

  • Handles multipart/form-data POST requests at /public-upload
  • No authentication required - uses link prefix validation
  • Validates canUpload flag and link expiration
  • Only works for folders (directories)
  • Creates files in the shared folder directory
  • Returns UploadResult model for type-safe response

UploadResult Model:

  • Type-safe response for upload operations
  • Contains: success (bool), filePath (String), fileName (String)
  • Serializable through Serverpod protocol
  • Used consistently across all upload endpoints

Files Endpoint - Public Listing:

  • listPublic(linkPrefix) - Lists files in publicly shared folders
  • Validates link exists, hasn't expired, and has canUpload=true
  • Only works for directory links
  • Returns same FsEntry stream as authenticated list

Links Endpoint:

  • getPublicLinkInfo(linkPrefix) - Gets link metadata without authentication
  • Returns null for expired links
  • Used to check link validity and canUpload flag

PublicSharedFolderScreen:

  • Displays files in publicly shared folders
  • Accessed via /public-shared-folder route with linkPrefix query parameter
  • Uses getPublicLinkInfo to validate link before showing files
  • Uses listPublic to fetch file list without authentication
  • Shows error message if link is invalid, expired, or doesn't allow uploads
  • Reuses FileTile component for consistent file display
  • Properly translates all UI text
  • Handles tap events on files/folders with informative messages
  • Includes upload button placeholder in app bar

UploadProgressDialog:

  • Instance method with builder => this pattern
  • Shows all uploads (pending, active, completed, failed)
  • Progress bars with percentage for active uploads
  • Color-coded status messages
  • Clear completed uploads button
  • Can't be dismissed while uploads are active (barrierDismissible: false)

📦 Dependencies Added

  • file_picker: ^10.3.6 (Flutter) - For selecting files to upload
  • mime: ^2.0.0 (Server) - For parsing multipart form data

🔒 Security

  • Authenticated uploads require authentication and folder access validation
  • Public uploads validate link prefix, canUpload flag, and expiration
  • Upload path validation prevents directory traversal attacks
  • Admin users have full access, regular users limited to their folders
  • Public links with canUpload only work for folders, not files
  • Public file listing validates link and canUpload before returning files

🌐 Public Link Upload Flow

  1. User creates shared link for a folder with canUpload=true
  2. Link recipient accesses the public link
  3. App redirects to /public-shared-folder?linkPrefix={key}
  4. App calls getPublicLinkInfo(linkPrefix) to validate link
  5. App calls listPublic(linkPrefix) to display folder contents with FileTile components
  6. Files can be uploaded to /public-upload with linkPrefix and file data
  7. Server validates link, checks canUpload flag, and saves file to folder
  8. Server returns UploadResult with success status and file info

Next Steps (Future Enhancements)

The following could be added in future iterations:

  1. Implement public file upload UI in PublicSharedFolderScreen
  2. Add file download functionality in public view
  3. Add folder navigation in public view
  4. Drag-and-drop file upload
  5. Folder upload support
  6. Upload resume capability
  7. Thumbnail generation for images
  8. Duplicate file handling options
Original prompt

This section details on the original issue you should resolve

<issue_title>Sharing upload link + Upload functionality</issue_title>
<issue_description>Users can share a link with permission to upload new files to folder
Users can upload new files and folders
Show notification with progress and ability to cancel upload.
Show page with your current upload progress</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits November 12, 2025 13:50
Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
Copilot AI changed the title [WIP] Add upload functionality with sharing link feature Add upload permission field to shared links Nov 12, 2025
Copilot AI requested a review from Asion001 November 12, 2025 14:01
@Asion001
Copy link
Owner

@copilot You forgot about uploading interface in app with progress screen/dialog.

- Add FileUploadController to manage upload state and progress
- Create UploadProgressDialog to show upload progress with cancel ability
- Add upload button to files bar with active upload badge
- Implement file picker integration for selecting multiple files
- Create FileUploadRoute on server to handle multipart file uploads
- Add upload-related localization strings
- Add file_picker and mime dependencies

Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 12, 2025

@copilot You forgot about uploading interface in app with progress screen/dialog.

Added complete file upload interface with progress tracking in commit f3ed906.

Features implemented:

  • Upload button in files bar (upload icon) to select and upload multiple files
  • Upload progress dialog showing real-time progress with percentage, bytes uploaded, and status for each file
  • Active upload badge displaying number of uploads in progress (click to view details)
  • Cancel capability for individual uploads with X button
  • File picker integration using file_picker package for selecting multiple files
  • Server upload endpoint (/upload) handling multipart file uploads with authentication
  • Automatic refresh of file list after successful uploads
  • Toast notifications for upload start, completion, and errors

The upload dialog shows all uploads with status indicators (pending, uploading, completed, failed, cancelled) and can't be dismissed while uploads are active. Users can clear completed uploads to keep the list clean.

Copilot AI changed the title Add upload permission field to shared links Add upload permission field to shared links and file upload interface Nov 12, 2025
Copy link
Owner

@Asion001 Asion001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Also I want canUpload flag for public links only be used for folder, after opening link to folder url will be redirected to public route on app with query parameter with link key. This key allows to list files in this specific folder

Copilot AI and others added 2 commits November 12, 2025 19:29
- Change UploadProgressDialog.show to instance method with builder => this
- Update file_picker version to 10.3.6
- Implement proper folder access validation in FileUploadRoute (same as files_endpoint)
- Use shared models for response serialization instead of jsonEncode

Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
- Create PublicUploadRoute to handle uploads via shared links without authentication
- Add listPublic endpoint to list files in publicly shared folders
- Add getPublicLinkInfo endpoint to get link metadata without auth
- Validate canUpload flag and link expiration for public uploads
- Register /public-upload route in server
- Public uploads only work for folders with canUpload=true

Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 12, 2025

@copilot Also I want canUpload flag for public links only be used for folder, after opening link to folder url will be redirected to public route on app with query parameter with link key. This key a...

Implemented public link upload for folders in commit 195b7cf.

Server endpoints added:

  • /public-upload - Accepts file uploads with linkPrefix (no authentication required)
  • files.listPublic(linkPrefix) - Lists files in publicly shared folder
  • links.getPublicLinkInfo(linkPrefix) - Gets link metadata without auth

Features:

  • canUpload flag only works for folders (directories)
  • Validates link exists, hasn't expired, and has canUpload=true
  • Public uploads save files directly to the shared folder
  • No authentication required - uses link prefix for validation

Usage flow:

  1. Create shared link for folder with canUpload=true
  2. App calls getPublicLinkInfo(linkPrefix) to check if upload allowed
  3. App calls listPublic(linkPrefix) to show folder contents
  4. Upload files to /public-upload with linkPrefix parameter

The frontend app can now create a public route that accepts the link key as a query parameter and provides the upload interface.

Copilot AI and others added 2 commits November 12, 2025 19:48
- Create UploadResult model with success, filePath, and fileName fields
- Update FileUploadRoute and PublicUploadRoute to use UploadResult
- Generate server and client protocol files for UploadResult
- Update serialization managers to handle UploadResult

Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
- Create PublicSharedFolderScreen to display files in publicly shared folders
- Add route at /public-shared-folder with linkPrefix query parameter
- Use listPublic endpoint to fetch files without authentication
- Validate link with getPublicLinkInfo before showing files
- Display error message if link is invalid or doesn't allow uploads
- Show file list with icons, names, sizes, and dates
- Add upload button in app bar (UI placeholder)
- Reuse existing file list UI patterns

Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
- Add translation for "No files in this folder" message
- Reuse FileTile component for consistent file display
- Add tap handlers for files and folders (with info messages)
- Use proper BorderRadius and padding matching file list patterns

Co-authored-by: Asion001 <46422813+Asion001@users.noreply.github.com>
- Created `shared_link` table with columns: id, createdBy, serverPath, linkPrefix, deleteAfter, canUpload.
- Created `user_folder_access` table with columns: id, userId, folderPath.
- Added foreign keys and indexes for both tables.
- Implemented migration scripts in JSON and SQL formats for the new tables.
- Updated migration registry to include the new migration version.
- Updated dependencies in `pubspec.yaml` and `pubspec.lock` to version 2.9.2 for serverpod packages.
- Enhanced test tools with new endpoints for admin, files, links, and user management.
@Asion001 Asion001 changed the title Add upload permission field to shared links and file upload interface feat: Add upload permission field to shared links and file upload interface Nov 12, 2025
@Asion001 Asion001 marked this pull request as ready for review November 12, 2025 23:45
@Asion001 Asion001 merged commit c3dfd3e into main Nov 12, 2025
4 checks passed
@Asion001 Asion001 deleted the copilot/add-upload-functionality branch November 12, 2025 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sharing upload link + Upload functionality

2 participants