Files
pnger/INSTRUCTIONS.md

8.2 KiB

PNGer Development Instructions

Project Overview

PNGer is a single-container web application for PNG editing and resizing, designed for deployment on Unraid with Gitea version control.

Development Roadmap

Phase 1: MVP Foundation (Completed )

  • Repository setup
  • Project structure initialization
  • Backend API scaffold
  • Frontend scaffold
  • Basic upload/download flow
  • Dockerfile configuration
  • Live preview implementation
  • Dark/light mode theming
  • Image resize and compression
  • Format conversion (PNG, WebP, JPEG)

Phase 2: Sprint 1 - Enhanced UX (Completed )

  • Drag & drop file upload
  • Clipboard paste (Ctrl+V)
  • Smart presets (8 configurations)
  • Keyboard shortcuts (Enter, Ctrl+Enter, ?, Esc)
  • Enhanced visual feedback
  • Responsive UI improvements
  • Theme contrast fixes

Phase 3: Advanced Features (Upcoming)

  • Batch processing
  • Advanced crop tool with visual selector
  • Watermarking
  • Image filters and effects
  • Undo/redo functionality
  • History/recent files

Technical Architecture

Backend (Express + Sharp)

Endpoints:

  • POST /api/transform - Transform image (resize, crop, compress, convert)
  • GET /api/health - Health check

Key Dependencies:

  • express: Web framework
  • multer: File upload handling
  • sharp: Image processing
  • cors: Cross-origin support

Frontend (Svelte + Vite)

Components:

  • App.svelte - Main container with all features
  • lib/api.ts - API client
  • lib/preview.ts - Live preview logic using Canvas API
  • lib/theme.ts - Dark/light theme management
  • lib/presets.ts - Smart presets configuration

Key Features:

  • Drag & drop upload
  • Clipboard paste support
  • Real-time preview (debounced 300ms)
  • Side-by-side comparison
  • File size analysis
  • 8 smart presets
  • Keyboard shortcuts
  • Persistent theme preference

Key Dependencies:

  • svelte: Reactive framework
  • vite: Build tool
  • axios: HTTP client

Docker Strategy

Multi-stage Build:

  1. Stage 1: Build frontend (Vite build)
  2. Stage 2: Copy frontend + setup backend
  3. Final image: Alpine-based Node.js

Image Size Target: < 150MB

Local Development Setup

Prerequisites

  • Node.js 20+
  • npm or pnpm
  • Docker (optional)

Initial Setup

# Clone repository
git clone https://git.alwisp.com/jason/pnger.git
cd pnger

# Setup backend
cd backend
npm install
npm run dev

# Setup frontend (new terminal)
cd frontend
npm install
npm run dev

Development Workflow

  1. Feature Branch: Create from main
  2. Develop: Make changes with hot-reload
  3. Test: Manual testing + health checks
  4. Commit: Descriptive commit messages
  5. Push: Push to Gitea
  6. Review: Self-review changes
  7. Merge: Merge to main

Environment Variables

Backend (.env):

PORT=3000
NODE_ENV=development
MAX_FILE_SIZE=10485760
CORS_ORIGIN=http://localhost:5173

Frontend (.env):

VITE_API_URL=http://localhost:3000/api

Docker Build & Test

# Build image
docker build -t pnger:test .

# Run container
docker run -p 8080:3000 --name pnger-test pnger:test

# Test endpoints
curl http://localhost:8080/api/health

# View logs
docker logs pnger-test

# Stop and remove
docker stop pnger-test && docker rm pnger-test

Unraid Deployment

Setup Steps

  1. SSH into Unraid
  2. Navigate to docker configs: /mnt/user/appdata/pnger
  3. Clone repository:
    git clone https://git.alwisp.com/jason/pnger.git
    cd pnger
    
  4. Build and run:
    docker-compose up -d
    
  5. Access: http://[unraid-ip]:8080

Update Process

cd /mnt/user/appdata/pnger
git pull origin main
docker-compose down
docker-compose build
docker-compose up -d

Code Standards

JavaScript/TypeScript

  • Use ES6+ features
  • Async/await for asynchronous operations
  • Descriptive variable names
  • Comments for complex logic only
  • Type safety with TypeScript

File Organization

  • One component per file
  • Group related utilities
  • Keep components under 300 lines (split if larger)
  • Organize by feature when possible

Commit Messages

  • Format: type: description
  • Types: feat, fix, docs, style, refactor, test, chore
  • Example: feat: add drag and drop upload
  • Be specific and descriptive

Feature Implementation Notes

Drag & Drop Upload

  • Uses HTML5 Drag and Drop API
  • Visual feedback on dragover/dragleave
  • File type validation on drop
  • Falls back to file input for browser support

Clipboard Paste

  • Listens for paste events on document
  • Extracts image from clipboard items
  • Supports screenshots and copied images
  • Works across all major browsers

Smart Presets

  • 8 predefined configurations:
    1. Web Optimized (1920x1080, 80%, WebP)
    2. Social Media (1080x1080, 85%, JPEG)
    3. Profile Picture (400x400, 90%, PNG)
    4. Email Friendly (800x600, 75%, JPEG)
    5. Tiny Icon (64x64, 100%, PNG)
    6. Retina 2x (2x size, 90%)
    7. Icon Small (256x256, 95%, PNG)
    8. Icon Large (512x512, 95%, PNG)
  • Applies all settings with one click
  • Visual icons for easy identification

Keyboard Shortcuts

  • Global document listeners
  • Context-aware Enter key (checks focus)
  • Help dialog with ? key
  • Esc to close dialogs
  • Cross-platform support (Ctrl/Cmd)

Live Preview

  • Client-side Canvas API rendering
  • Debounced updates (300ms)
  • Reactive state management
  • Automatic size estimation
  • Side-by-side comparison

Troubleshooting

Common Issues

Port already in use:

lsof -ti:3000 | xargs kill -9

Sharp installation issues:

npm rebuild sharp

Docker build fails:

  • Check Docker daemon is running
  • Verify Dockerfile syntax
  • Clear Docker cache: docker builder prune

Preview not updating:

  • Check browser console for errors
  • Verify Canvas API support
  • Clear browser cache

Drag & drop not working:

  • Check file type validation
  • Verify event handlers are attached
  • Test with different browsers

Performance Targets

  • Upload handling: < 100ms (for 5MB file)
  • Image processing: < 2s (for 10MP image)
  • Download generation: < 500ms
  • UI response time: < 100ms
  • Preview generation: < 500ms (client-side)
  • Docker image size: < 150MB

Security Considerations

  • File type validation (image/* only)
  • File size limits (10MB default, configurable)
  • No persistent storage of user files
  • Memory cleanup after processing
  • CORS configuration
  • Input sanitization
  • Error message sanitization (no path disclosure)

Testing Checklist

Upload Methods

  • File input (click to browse)
  • Drag & drop
  • Clipboard paste (Ctrl+V)
  • File validation errors
  • Size limit handling

Image Operations

  • Resize with width only
  • Resize with height only
  • Resize with both dimensions
  • Crop to fit (cover mode)
  • All 9 crop positions
  • Format conversion (PNG, WebP, JPEG)
  • Quality adjustment

Presets

  • All 8 presets apply correctly
  • Preset values match specifications
  • Visual feedback on selection

Keyboard Shortcuts

  • Ctrl+V pastes image
  • Enter downloads (not in input)
  • Ctrl+Enter downloads (anywhere)
  • ? shows help dialog
  • Esc closes dialog

UI/UX

  • Theme toggle works
  • Theme persists on reload
  • Live preview updates
  • File size analysis accurate
  • Error messages clear
  • Loading states visible
  • Responsive on mobile

Browser Compatibility

  • Chrome/Edge
  • Firefox
  • Safari
  • Mobile browsers

Next Steps

  1. Create backend folder structure
  2. Create frontend folder structure
  3. Initialize package.json files
  4. Create Dockerfile
  5. Create docker-compose.yml
  6. Implement MVP features
  7. Add drag & drop upload
  8. Add clipboard paste
  9. Add smart presets
  10. Add keyboard shortcuts
  11. Implement batch processing
  12. Add advanced crop tool
  13. Add watermarking
  14. Add filters/effects

Resources