π€ File Upload & Media Components
Status: Implemented and documented (Feb 2026)
π Overview
Comprehensive file upload system with image editing, asset picking, and multi-file support.
π§± Components
β¬οΈ FileUploader (ui/media/FileUploader.svelte)
Multi-file uploader with:
- Drag & drop support
- Click to browse
- File type & size validation
- Image files β automatic ImageEditModal opening
- Non-image files β FileEditModal for rename
- Edit (βοΈ) and Restore (β©οΈ) buttons per file
- Preview for images via backend thumbnail API
βοΈ ImageCropper (ui/media/ImageCropper.svelte)
cropperjs v2 based image cropper (Web Components):
- Free crop with L-shaped corner handles
- Zoom via buttons, mouse wheel, or pinch
- Rotation (15Β° steps) relative to selection center
- Flip horizontal/vertical
- Aspect ratio presets (free, 1:1, 4:3, 16:9)
- Selection clamped to canvas bounds
- Middle-mouse-button drag for background translation
πΌοΈ ImageEditModal (ui/media/ImageEditModal.svelte)
Full image editing modal (extends ModalBase):
- Presets: Avatar (200Γ200), Icon (64Γ64), Custom (free)
- Output size with editable width/height + auto scale
- Format selection (PNG, JPEG, WebP)
- Quality control for lossy formats (10-100%)
- Ellipse preview overlay (for avatar/icon circular display)
- Confirmation dialog on close with unsaved changes
- Reset all button to restore original state
π FileEditModal (ui/media/FileEditModal.svelte)
Simple file rename modal (extends ModalBase):
- Rename file before upload
- Used for PDFs, CSVs, and other non-image files
- Also available for BRIM import files
π AssetPickerModal (ui/media/AssetPickerModal.svelte)
3-tab asset picker modal (extends ModalBase):
- Existing: Browse uploaded files with DataTable or FileGrid
- URL: Enter a URL with live preview and circular overlay
- Upload: Upload + crop a new image
Used for: broker icons, user avatars, and any image URL field.
πΈ ImagePickerWrapper (ui/media/ImagePickerWrapper.svelte)
Wraps the full AssetPicker β ImageEdit flow:
- Opens AssetPickerModal
- If upload selected β opens ImageEditModal
- Returns final URL to parent
π FileGrid (ui/media/FileGrid.svelte)
Shared grid view component used in both /files page and AssetPickerModal.
π Files
frontend/src/lib/components/ui/media/
βββ AssetPickerModal.svelte
βββ FileEditModal.svelte
βββ FileGrid.svelte
βββ FileUploader.svelte
βββ ImageCropper.svelte
βββ ImageEditModal.svelte
βββ ImagePickerWrapper.svelte
βββ ImageUploader.svelte
βββ LazyImage.svelte
βββ index.ts
Backend Support
- Image preview API:
GET /api/v1/uploads/file/{id}?img_preview=WxH - Preview cache: Size-based (
PREVIEW_CACHE_MAX_MBin.env, default 50MB), TTL 1h, invalidated on delete - No-op for small images: If requested size β₯ original, serves file directly without processing
- Seed avatars: 30 default avatar PNGs copied to
custom-uploads/on first startup viaseed_default_avatars() - Upload utility: Centralized
uploadFile()inutils/upload.tsβ single FormData creation point - Size formatting: Centralized i18n-aware
formatBytes()inutils/upload.ts
Validation
- File type checking against
acceptprop - File size checking against global
max_file_upload_mbsetting - Client-side only (server validates again)