# Image Uploader with Multi-Upload & Slideshow A self-hosted image uploader with multi-image upload capabilities and automatic slideshow functionality. ## Features **Multi-Image Upload**: Upload multiple images at once with batch processing **Slideshow Mode**: Automatic fullscreen slideshow with smooth transitions **Persistent Storage**: Docker volumes ensure data persistence across restarts **Clean UI**: Minimalist design focused on user experience **Self-Hosted**: Complete control over your data and infrastructure **Lightweight**: Built with modern web technologies for optimal performance ## What's New This project extends the original [Image-Uploader by vallezw](https://github.com/vallezw/Image-Uploader) with enhanced multi-upload and slideshow capabilities. - Multi-image batch upload with progress tracking - Automatic slideshow presentation mode - Image grouping with descriptions - Random slideshow rotation - Keyboard navigation support - Mobile-responsive design- Mobile-responsive design ## Quick Start ### Docker Deployment (Recommended) 1. **Create docker-compose.yml**: ```yaml services: frontend: image: vallezw/image-uploader-client ports: - "80:80" depends_on: - backend environment: - "API_URL=http://localhost:5000" - "CLIENT_URL=http://localhost" container_name: frontend backend: image: vallezw/image-uploader-backend environment: - "CLIENT_URL=http://localhost" container_name: backend backend: image: vallezw/image-uploader-client ports: - "80:80" container_name: frontend image: vallezw/image-uploader-backend ports: - "5000:5000" container_name: backend volumes: - app-data:/usr/src/app/src/upload depends_on: - app-data:/usr/src/app/src/data - backend volumes: app-data: environment: - "API_URL=http://localhost:5000" - "CLIENT_URL=http://localhost" driver: local ``` 2. **Start the application**: ```bash docker compose up -d ``` 3. **Access the application**: - Upload Interface: `http://localhost` - Backend: `http://localhost:5000` - Slideshow Mode: `http://localhost/slideshow` ### Multi-Image Upload 1. Visit `http://localhost` 2. Drag & drop multiple images or click to select 3. Add an optional description for your image collection 4. Click "Upload Images" to process the batch 5. Images are automatically grouped for slideshow viewing ### Slideshow Mode - **Automatic Access**: Navigate to `http://localhost/slideshow` - **Features**: - Fullscreen presentation - 4-second display per image - Automatic progression through all slideshow collections - Random selection of next slideshow after completing current one - Smooth fade transitions (0.5s) - **Keyboard Controls**: - **ESC**: Exit slideshow / Return to upload page - **Spacebar / Arrow Right**: Manually advance to next image - **Home Button**: Return to main upload interface ### Moderation Interface (Protected) - **Access**: `http://localhost/moderation` (requires authentication) - **Authentication**: HTTP Basic Auth (username: admin, password: set during setup) - **Features**: - Review pending image groups before public display - Approve or reject submitted collections - Delete individual images from approved groups - View group details (title, creator, description, image count) - Bulk moderation actions - **Group Management**: Navigate to `http://localhost/groups` (requires authentication) - Overview of all approved slideshow collections - Delete entire groups - Launch slideshow mode from any group - View group statistics and metadata **Security Features**: - Password protected access via nginx HTTP Basic Auth - Hidden from search engines (`robots.txt` + `noindex` meta tags) - No public links or references in main interface ## Data Structure ### Slideshow JSON Format ```json [ { "groupId": "0fSwazTOU", "description": "My Photo Collection", "uploadDate": "2025-10-11T14:34:48.159Z", "images": { "fileName": "ZMmHXzHbqw.jpg", "originalName": "vacation-photo-1.jpg", "filePath": "/upload/ZMmHXzHbqw.jpg", "uploadOrder": 1 }, { "fileName": "tjjnngOmXS.jpg", "originalName": "vacation-photo-2.jpg", "filePath": "/upload/tjjnngOmXS.jpg", "uploadOrder": 2 } ], "imageCount": 21 } ] ``` ### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `groupId` | string | Unique identifier generated with shortid | | `description` | string | User-provided description for the image collection | | `uploadDate` | string | ISO timestamp of upload completion | | `images` | array | Array of image objects in the collection | | `imageCount` | number | Total number of images in the group | ### Image Object Structure | Field | Type | Description | |-------|------|-------------| | `fileName` | string | Generated unique filename for storage | | `originalName` | string | Original filename from user's device | | `filePath` | string | Relative path to the stored image file | | `uploadOrder` | number | Sequential order within the slideshow (1, 2, 3...) | ## Architecture ### Backend (Node.js + Express) - **Multi-upload API**: `/api/upload/batch` - Handles batch file processing - **Groups API**: `/api/groups` - Retrieves slideshow collections - **File Storage**: Organized in `/upload` directory - **Metadata Storage**: JSON files in `/data` directory ### Frontend (React + Material-UI) - **Multi-Upload Interface**: Drag & drop with preview gallery - **Progress Tracking**: Real-time upload status - **Spacebar / Arrow Right**: Manually advance to next image - **Slideshow Engine**: Fullscreen presentation with automatic progression - **Responsive Design**: Mobile and desktop optimized - **Home Button**: Return to main upload interface ### Storage Architecture ``` Docker Volume (app-data) ├── upload/ │ ├── ZMmHXzHbqw.jpg │ ├── tjjnngOmXS.jpg │ └── ...### Slideshow JSON Format └── data/ # Metadata └── upload-groups.json ``` ### Hosting it with Docker - **Frontend**: React 17, Material-UI, React Router - **Backend**: Node.js, Express, Multer (file handling) - **Containerization**: Docker, Docker Compose - **Reverse Proxy**: nginx (routing & file serving)[In order to host the project you will need to create a docker-compose file. These files are combining multiple docker images to interact with each other. - **File Upload**: Drag & drop with react-dropzone - **Notifications**: SweetAlert2 ## API Endpoints ### Upload Operations - `POST /api/upload/batch` - Upload multiple images with description - `GET /api/groups` - Retrieve all slideshow groups - `GET /api/groups/:id` - Get specific slideshow group ### Moderation Operations (Protected) - `GET /moderation/groups` - Get all groups pending moderation - `POST /groups/:id/approve` - Approve a group for public display - `DELETE /groups/:id` - Delete an entire group - `DELETE /groups/:id/images/:imageId` - Delete individual image from group ### File Access - `GET /api/upload/:filename` - Access uploaded image files ## Configuration ### Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `API_URL` | `http://localhost:5000` | Backend API endpoint | | `CLIENT_URL` | `http://localhost` | Frontend application URL | ### Volume Configuration - **Data Persistence**: `/usr/src/app/src/upload` and `/usr/src/app/src/data` mounted to `app-data` - **Upload Limits**: 100MB maximum file size for batch uploads - **Supported Formats**: JPG, JPEG, PNG, GIF, WebP ### Custom Deployment For production deployment, modify the docker-compose configuration: ```yaml environment: - "API_URL=https://your-domain.com/api" - "CLIENT_URL=https://your-domain.com" ``` ### Backup & Restore #### Backup slideshow data ```sh docker cp backend:/usr/src/app/src/data ./backup-data docker cp backend:/usr/src/app/src/upload ./backup-images ``` #### Restore slideshow data ```sh docker cp ./backup-data backend:/usr/src/app/src/data docker cp ./backup-images backend:/usr/src/app/src/upload ``` ## Contributing Contributions are welcome! This project extends the original work by [vallezw](https://github.com/vallezw/Image-Uploader). ### Development Setup 1. Fork the repository 2. Create feature branch: `git checkout -b feature/amazing-feature` 3. Commit changes: `git commit -m 'Add amazing feature'` 4. Push to branch: `git push origin feature/amazing-feature`| Field | Type | Description |#### Changing the URL 5. Open a Pull Request ## License This project is distributed under the MIT License. See `LICENSE` for more information. ## Acknowledgments - Original project: [Image-Uploader by vallezw](https://github.com/vallezw/Image-Uploader)