Skip to content

Comments

Add drag-and-drop image upload feature#136

Merged
neonwatty merged 2 commits intomainfrom
feature/drag-drop-image-upload
Nov 18, 2025
Merged

Add drag-and-drop image upload feature#136
neonwatty merged 2 commits intomainfrom
feature/drag-drop-image-upload

Conversation

@neonwatty
Copy link
Owner

Summary

Implements a drag-and-drop image upload interface allowing users to upload meme images directly through the web UI. Uploaded files are saved to a Docker volume mount for persistence.

Features

  • ✅ Drag-and-drop file upload with client-side validation (JPEG, PNG, WEBP)
  • ✅ File size limit (10MB) and type validation
  • ✅ Filename sanitization to prevent path traversal attacks
  • ✅ Auto-creates "direct-uploads" ImagePath on first upload
  • ✅ Triggers automatic directory scan to create ImageCore records
  • ✅ Upload link visible in main navigation
  • ✅ Files saved to Docker volume mount (./meme_search/direct-uploads/)
  • ✅ Accessible to both Rails and Python services

Implementation Details

Backend:

  • ImageUploadsController: Handles file validation, sanitization, and saving
  • ImagePath.ensure_direct_uploads_path!: Auto-creates upload path on first use
  • CSRF token handling with null check for test environment

Frontend:

  • Stimulus file_upload_controller.js: Drag-drop UI with preview
  • Glassmorphic design consistent with app theme
  • Real-time file validation and error messages

Docker:

  • Volume mounts in both compose files for persistence
  • Files accessible at /rails/public/memes/direct-uploads/ (Rails)
  • Files accessible at /app/public/memes/direct-uploads/ (Python)

Testing

  • ✅ 9 Rails controller tests (all passing)
  • ✅ 8 Playwright E2E tests (all passing)
    • Page display and navigation
    • Single and multiple file uploads
    • File type and size validation
    • ImagePath auto-creation
    • Navigation link visibility
  • ✅ Full test suite: 203 Rails tests + 56 E2E tests (all passing)

Test Plan

  • Upload single image via drag-drop
  • Upload multiple images simultaneously
  • Verify file type validation (reject PDFs, TXT files)
  • Verify file size validation (reject files > 10MB)
  • Verify filename sanitization (prevent path traversal)
  • Verify auto-creation of "direct-uploads" ImagePath
  • Verify files persist in Docker volume
  • Verify Upload link visible in navigation
  • Verify files accessible to both Rails and Python services

🤖 Generated with Claude Code

Jeremy Watt and others added 2 commits November 17, 2025 16:18
Implements a new drag-and-drop image upload interface that allows users to upload meme images directly through the web UI. Uploaded files are saved to a Docker volume mount for persistence across container restarts.

Features:
- Drag-and-drop file upload with client-side validation (JPEG, PNG, WEBP)
- File size limit (10MB) and type validation
- Filename sanitization to prevent path traversal attacks
- Auto-creates "direct-uploads" ImagePath on first upload
- Triggers automatic directory scan to create ImageCore records
- Upload link visible in main navigation between "Search memes" and "Settings"
- Files saved to Docker volume mount (./meme_search/direct-uploads/)
- Accessible to both Rails and Python services

Implementation:
- Backend: ImageUploadsController with validation and file handling
- Frontend: Stimulus file_upload_controller.js for drag-drop UI
- View: Glassmorphic design consistent with app theme
- Docker: Volume mounts in both compose files for file persistence
- Tests: 9 Rails controller tests + 8 Playwright E2E tests (all passing)

Technical details:
- CSRF token handling with null check for test environment compatibility
- Rails ImagePath.ensure_direct_uploads_path! method for auto-setup
- Sanitized filenames preserve original names while preventing security issues
- Manual processing workflow (not auto-processed)
- Single flat directory organization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Enhances the drag-and-drop image upload feature with 8 key improvements
for production readiness: security hardening, better error handling,
improved UX, and comprehensive testing.

Backend improvements:
- Add MIME type validation using Marcel gem to prevent malicious files
  disguised as images (security hardening)
- Add duplicate filename handling with timestamp appending to prevent
  data loss from silent overwrites
- Add specific error messages for disk full (ENOSPC) and permission
  denied (EACCES) errors with Docker troubleshooting guidance
- Improve filename sanitization to preserve unicode characters
  (Chinese, Japanese, emoji) while removing dangerous chars
- All error handling now provides actionable, user-friendly messages

Frontend improvements:
- Replace fetch() with XMLHttpRequest for real-time upload progress
  tracking with percentage display
- Add client-side file size validation (10MB limit) to prevent wasted
  time uploading oversized files
- Add bulk upload limit (50 files max) to prevent browser freezing
- Add auto-redirect to home page after successful upload so users
  immediately see their uploaded images
- Add comprehensive console logging for debugging

UX improvements:
- Update "How it works" messaging to explain Docker volume mount
  concept and default path location
- Progress bar now shows real upload percentage
- Clear error messages guide users to solutions

Testing:
- Add 3 new controller tests for edge cases (duplicate filenames,
  MIME validation, unicode filenames)
- Update test helper to create valid JPEG images for MIME validation
- All 12 controller tests passing
- All 197 Rails tests passing
- All 56 E2E tests passing (8 upload-specific tests)

Files modified:
- app/controllers/image_uploads_controller.rb: +105 lines
  - MIME validation, duplicate handling, error messages, unicode support
- app/javascript/controllers/file_upload_controller.js: +45 lines
  - XHR progress tracking, file size validation, bulk limit, redirect
- app/views/image_uploads/new.html.erb: ~10 lines
  - Updated Docker volume mount messaging
- test/controllers/image_uploads_controller_test.rb: +80 lines
  - Fixed helper, added 3 edge case tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@neonwatty neonwatty merged commit 9b892b3 into main Nov 18, 2025
5 checks passed
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.

1 participant