# Frontend Integration Guide Complete guide for integrating the existing frontend assets with the FastAPI backend. ## Table of Contents 1. [Overview](#overview) 2. [Frontend Asset Structure](#frontend-asset-structure) 3. [API Integration](#api-integration) 4. [WebSocket Integration](#websocket-integration) 5. [Theme System](#theme-system) 6. [Authentication Flow](#authentication-flow) 7. [Error Handling](#error-handling) 8. [Localization](#localization) 9. [Accessibility Features](#accessibility-features) 10. [Testing Integration](#testing-integration) ## Overview The Aniworld frontend uses vanilla JavaScript with modern ES6+ features, integrated with a FastAPI backend through REST API endpoints and WebSocket connections. The design follows Fluent UI principles with comprehensive accessibility support. ### Key Technologies - **Frontend**: Vanilla JavaScript (ES6+), HTML5, CSS3 - **Backend**: FastAPI, Python 3.10+ - **Communication**: REST API, WebSocket - **Styling**: Custom CSS with Fluent UI design principles - **Icons**: Font Awesome 6.0.0 ## Frontend Asset Structure ### Templates (`src/server/web/templates/`) - `index.html` - Main application interface - `queue.html` - Download queue management page - `login.html` - Authentication login page - `setup.html` - Initial setup page - `error.html` - Error display page ### JavaScript Files (`src/server/web/static/js/`) #### Core Application Files - **`app.js`** (2086 lines) - Main application logic - Series management - Download operations - Search functionality - Theme management - Authentication handling - **`queue.js`** (758 lines) - Download queue management - Queue reordering - Download progress tracking - Queue status updates - **`websocket_client.js`** (234 lines) - Native WebSocket wrapper - Socket.IO-like interface - Reconnection logic - Message routing #### Feature Enhancement Files - **`accessibility_features.js`** - ARIA labels, keyboard navigation - **`advanced_search.js`** - Advanced search filtering - **`bulk_operations.js`** - Batch operations on series - **`color_contrast_compliance.js`** - WCAG color contrast validation - **`drag_drop.js`** - Drag-and-drop queue reordering - **`keyboard_shortcuts.js`** - Global keyboard shortcuts - **`localization.js`** - Multi-language support - **`mobile_responsive.js`** - Mobile-specific enhancements - **`multi_screen_support.js`** - Multi-monitor support - **`screen_reader_support.js`** - Screen reader compatibility - **`touch_gestures.js`** - Touch gesture support - **`undo_redo.js`** - Undo/redo functionality - **`user_preferences.js`** - User preference management ### CSS Files (`src/server/web/static/css/`) - **`styles.css`** - Main stylesheet with Fluent UI design - **`ux_features.css`** - UX enhancements and accessibility styles ## API Integration ### Current API Endpoints Used #### Authentication Endpoints ```javascript // Check authentication status GET /api/auth/status Headers: { Authorization: Bearer } // Login POST /api/auth/login Body: { password: string } Response: { token: string, token_type: string } // Logout POST /api/auth/logout ``` #### Anime Endpoints ```javascript // List all anime GET /api/v1/anime Response: { success: bool, data: Array } // Search anime GET /api/v1/anime/search?query= Response: { success: bool, data: Array } // Get anime details GET /api/v1/anime/{anime_id} Response: { success: bool, data: Anime } ``` #### Download Queue Endpoints ```javascript // Get queue status GET /api/v1/download/queue Response: { queue: Array, is_running: bool } // Add to queue POST /api/v1/download/queue Body: { anime_id: string, episodes: Array } // Start queue POST /api/v1/download/queue/start // Stop queue POST /api/v1/download/queue/stop // Pause queue POST /api/v1/download/queue/pause // Resume queue POST /api/v1/download/queue/resume // Reorder queue PUT /api/v1/download/queue/reorder Body: { queue_order: Array } // Remove from queue DELETE /api/v1/download/queue/{item_id} ``` #### Configuration Endpoints ```javascript // Get configuration GET / api / v1 / config; Response: { config: ConfigObject; } // Update configuration PUT / api / v1 / config; Body: ConfigObject; ``` ### API Call Pattern All API calls follow this pattern in the JavaScript files: ```javascript async function apiCall(endpoint, options = {}) { try { const token = localStorage.getItem("access_token"); const headers = { "Content-Type": "application/json", ...(token && { Authorization: `Bearer ${token}` }), ...options.headers, }; const response = await fetch(endpoint, { ...options, headers, }); if (!response.ok) { if (response.status === 401) { // Redirect to login window.location.href = "/login"; return; } throw new Error(`HTTP ${response.status}: ${response.statusText}`); } return await response.json(); } catch (error) { console.error("API call failed:", error); throw error; } } ``` ### Required API Updates The following API endpoints need to be verified/updated to match frontend expectations: 1. **Response Format Consistency** - All responses should include `success` boolean - Error responses should include `error`, `message`, and `details` - Success responses should include `data` field 2. **Authentication Flow** - `/api/auth/status` endpoint for checking authentication - Proper 401 responses for unauthenticated requests - Token refresh mechanism (if needed) 3. **Queue Operations** - Ensure queue reordering endpoint exists - Validate pause/resume functionality - Check queue status polling endpoint ## WebSocket Integration ### WebSocket Connection The frontend uses a custom WebSocket client (`websocket_client.js`) that provides a Socket.IO-like interface over native WebSocket. #### Connection Endpoint ```javascript const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; const host = window.location.host; const wsUrl = `${protocol}//${host}/ws/connect`; ``` ### WebSocket Events #### Events Sent by Frontend ```javascript // Join a room (for targeted updates) socket.emit("join", { room: "downloads" }); socket.emit("join", { room: "download_progress" }); // Leave a room socket.emit("leave", { room: "downloads" }); // Custom events (as needed) socket.emit("custom_event", { data: "value" }); ``` #### Events Received by Frontend ##### Connection Events ```javascript socket.on("connect", () => { // Connection established }); socket.on("disconnect", (data) => { // Connection lost - data: { code, reason } }); socket.on("connected", (data) => { // Server confirmation - data: { message, timestamp } }); ``` ##### Queue Events ```javascript // Queue status updates socket.on("queue_status", (data) => { // data: { queue_status: { queue: [], is_running: bool } } }); socket.on("queue_updated", (data) => { // Legacy event - same as queue_status }); // Download lifecycle socket.on("queue_started", () => { // Queue processing started }); socket.on("download_started", (data) => { // Individual download started // data: { serie_name, episode } }); socket.on("download_progress", (data) => { // Download progress update // data: { serie_name, episode, progress, speed, eta } }); socket.on("download_complete", (data) => { // Download completed // data: { serie_name, episode } }); socket.on("download_completed", (data) => { // Legacy event - same as download_complete }); socket.on("download_failed", (data) => { // Download failed // data: { serie_name, episode, error } }); socket.on("download_error", (data) => { // Legacy event - same as download_failed }); socket.on("download_queue_completed", () => { // All downloads in queue completed }); socket.on("download_stop_requested", () => { // Queue stop requested }); ``` ##### Scan Events ```javascript socket.on("scan_started", () => { // Library scan started }); socket.on("scan_progress", (data) => { // Scan progress update // data: { current, total, percentage } }); socket.on("scan_completed", (data) => { // Scan completed // data: { total_series, new_series, updated_series } }); socket.on("scan_failed", (data) => { // Scan failed // data: { error } }); ``` ### Backend WebSocket Requirements The backend WebSocket implementation (`src/server/api/websocket.py`) should: 1. **Accept connections at** `/ws/connect` 2. **Handle room management** (join/leave messages) 3. **Broadcast events** to appropriate rooms 4. **Support message format**: ```json { "event": "event_name", "data": { ... } } ``` ## Theme System ### Theme Implementation The application supports light and dark modes with persistence. #### Theme Toggle ```javascript // Toggle theme document.documentElement.setAttribute("data-theme", "light|dark"); // Store preference localStorage.setItem("theme", "light|dark"); // Load on startup const savedTheme = localStorage.getItem("theme") || "light"; document.documentElement.setAttribute("data-theme", savedTheme); ``` #### CSS Variables Themes are defined using CSS custom properties: ```css :root[data-theme="light"] { --bg-primary: #ffffff; --bg-secondary: #f5f5f5; --text-primary: #000000; --text-secondary: #666666; --accent-color: #0078d4; /* ... more variables */ } :root[data-theme="dark"] { --bg-primary: #1e1e1e; --bg-secondary: #2d2d2d; --text-primary: #ffffff; --text-secondary: #cccccc; --accent-color: #60a5fa; /* ... more variables */ } ``` ### Fluent UI Design Principles The frontend follows Microsoft Fluent UI design guidelines: - **Rounded corners**: 4px border radius - **Shadows**: Subtle elevation shadows - **Transitions**: Smooth 200-300ms transitions - **Typography**: System font stack - **Spacing**: 8px grid system - **Colors**: Accessible color palette ## Authentication Flow ### Authentication States ```javascript // State management const authStates = { UNAUTHENTICATED: "unauthenticated", AUTHENTICATED: "authenticated", SETUP_REQUIRED: "setup_required", }; ``` ### Authentication Check On page load, the application checks authentication status: ```javascript async checkAuthentication() { // Skip check on public pages const currentPath = window.location.pathname; if (currentPath === '/login' || currentPath === '/setup') { return; } try { const token = localStorage.getItem('access_token'); if (!token) { window.location.href = '/login'; return; } const response = await fetch('/api/auth/status', { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { if (response.status === 401) { localStorage.removeItem('access_token'); window.location.href = '/login'; } } } catch (error) { console.error('Auth check failed:', error); window.location.href = '/login'; } } ``` ### Login Flow ```javascript async login(password) { try { const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password }) }); if (response.ok) { const data = await response.json(); localStorage.setItem('access_token', data.token); window.location.href = '/'; } else { // Show error message this.showError('Invalid password'); } } catch (error) { console.error('Login failed:', error); this.showError('Login failed'); } } ``` ### Logout Flow ```javascript async logout() { try { await fetch('/api/auth/logout', { method: 'POST' }); } finally { localStorage.removeItem('access_token'); window.location.href = '/login'; } } ``` ## Error Handling ### Frontend Error Display The application uses toast notifications for errors: ```javascript showToast(message, type = 'info') { const toast = document.createElement('div'); toast.className = `toast toast-${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.classList.add('show'); }, 100); setTimeout(() => { toast.classList.remove('show'); setTimeout(() => toast.remove(), 300); }, 3000); } ``` ### API Error Handling ```javascript async function handleApiError(error, response) { if (response) { const data = await response.json().catch(() => ({})); // Show user-friendly error message const message = data.message || `Error: ${response.status}`; this.showToast(message, "error"); // Log details for debugging console.error("API Error:", { status: response.status, error: data.error, message: data.message, details: data.details, }); // Handle specific status codes if (response.status === 401) { // Redirect to login localStorage.removeItem("access_token"); window.location.href = "/login"; } } else { // Network error this.showToast("Network error. Please check your connection.", "error"); console.error("Network error:", error); } } ``` ### Expected Error Response Format The backend should return errors in this format: ```json { "success": false, "error": "ERROR_CODE", "message": "Human-readable error message", "details": { "field": "error_field", "reason": "specific_reason" }, "request_id": "uuid" } ``` ## Localization The application includes a localization system (`localization.js`) for multi-language support. ### Localization Usage ```javascript // Initialize localization const localization = new Localization(); // Set language localization.setLanguage("en"); // or 'de', 'es', etc. // Get translation const text = localization.get("key", "default_value"); // Update all page text localization.updatePageText(); ``` ### Text Keys Elements with `data-text` attributes are automatically translated: ```html Download Queue ``` ### Adding New Translations Translations are defined in `localization.js`: ```javascript const translations = { en: { "download-queue": "Download Queue", "start-download": "Start Download", // ... more keys }, de: { "download-queue": "Download-Warteschlange", "start-download": "Download starten", // ... more keys }, }; ``` ## Accessibility Features The application includes comprehensive accessibility support. ### Keyboard Navigation All interactive elements are keyboard accessible: - **Tab/Shift+Tab**: Navigate between elements - **Enter/Space**: Activate buttons - **Escape**: Close modals/dialogs - **Arrow Keys**: Navigate lists Custom keyboard shortcuts are defined in `keyboard_shortcuts.js`. ### Screen Reader Support ARIA labels and live regions are implemented: ```html
``` ### Color Contrast The application ensures WCAG AA compliance for color contrast: - Normal text: 4.5:1 minimum - Large text: 3:1 minimum - Interactive elements: 3:1 minimum `color_contrast_compliance.js` validates contrast ratios. ### Touch Support Touch gestures are supported for mobile devices: - **Swipe**: Navigate between sections - **Long press**: Show context menu - **Pinch**: Zoom (where applicable) ## Testing Integration ### Frontend Testing Checklist - [ ] **API Integration** - [ ] All API endpoints return expected response format - [ ] Error responses include proper error codes - [ ] Authentication flow works correctly - [ ] Token refresh mechanism works (if implemented) - [ ] **WebSocket Integration** - [ ] WebSocket connects successfully - [ ] All expected events are received - [ ] Reconnection works after disconnect - [ ] Room-based broadcasting works correctly - [ ] **UI/UX** - [ ] Theme toggle persists across sessions - [ ] All pages are responsive (mobile, tablet, desktop) - [ ] Animations are smooth and performant - [ ] Toast notifications display correctly - [ ] **Authentication** - [ ] Login redirects to home page - [ ] Logout clears session and redirects - [ ] Protected pages redirect unauthenticated users - [ ] Token expiration handled gracefully - [ ] **Accessibility** - [ ] Keyboard navigation works on all pages - [ ] Screen reader announces important changes - [ ] Color contrast meets WCAG AA standards - [ ] Focus indicators are visible - [ ] **Localization** - [ ] All text is translatable - [ ] Language selection persists - [ ] Translations are complete for all supported languages - [ ] **Error Handling** - [ ] Network errors show appropriate messages - [ ] API errors display user-friendly messages - [ ] Fatal errors redirect to error page - [ ] Errors are logged for debugging ### Integration Test Examples #### API Integration Test ```javascript describe("API Integration", () => { test("should authenticate and fetch anime list", async () => { // Login const loginResponse = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ password: "test_password" }), }); const { token } = await loginResponse.json(); expect(token).toBeDefined(); // Fetch anime const animeResponse = await fetch("/api/v1/anime", { headers: { Authorization: `Bearer ${token}` }, }); const data = await animeResponse.json(); expect(data.success).toBe(true); expect(Array.isArray(data.data)).toBe(true); }); }); ``` #### WebSocket Integration Test ```javascript describe("WebSocket Integration", () => { test("should connect and receive events", (done) => { const socket = new WebSocketClient(); socket.on("connect", () => { expect(socket.isConnected).toBe(true); // Join room socket.emit("join", { room: "downloads" }); // Wait for queue_status event socket.on("queue_status", (data) => { expect(data).toHaveProperty("queue_status"); socket.disconnect(); done(); }); }); socket.connect(); }); }); ``` ## Frontend Integration Checklist ### Phase 1: API Endpoint Verification - [ ] Verify `/api/auth/status` endpoint exists and returns proper format - [ ] Verify `/api/auth/login` returns token in expected format - [ ] Verify `/api/auth/logout` endpoint exists - [ ] Verify `/api/v1/anime` returns list with `success` and `data` fields - [ ] Verify `/api/v1/anime/search` endpoint exists - [ ] Verify `/api/v1/download/queue` endpoints match frontend expectations - [ ] Verify error responses include `success`, `error`, `message`, `details` ### Phase 2: WebSocket Integration - [ ] Verify WebSocket endpoint is `/ws/connect` - [ ] Verify room join/leave functionality - [ ] Verify all queue events are emitted properly - [ ] Verify scan events are emitted properly - [ ] Test reconnection logic - [ ] Test message broadcasting to rooms ### Phase 3: Frontend Code Updates - [ ] Update `app.js` API calls to match backend endpoints - [ ] Update `queue.js` API calls to match backend endpoints - [ ] Verify `websocket_client.js` message format matches backend - [ ] Update error handling to parse new error format - [ ] Test authentication flow end-to-end - [ ] Verify theme persistence works ### Phase 4: UI/UX Polish - [ ] Verify responsive design on mobile devices - [ ] Test keyboard navigation on all pages - [ ] Verify screen reader compatibility - [ ] Test color contrast in both themes - [ ] Verify all animations are smooth - [ ] Test touch gestures on mobile ### Phase 5: Testing - [ ] Write integration tests for API endpoints - [ ] Write integration tests for WebSocket events - [ ] Write UI tests for critical user flows - [ ] Test error scenarios (network errors, auth failures) - [ ] Test performance under load - [ ] Test accessibility with screen reader ## Conclusion This guide provides a comprehensive overview of the frontend integration requirements. All JavaScript files should be reviewed and updated to match the documented API endpoints and WebSocket events. The backend should ensure it provides the expected response formats and event structures. For questions or issues, refer to: - **API Reference**: `docs/api_reference.md` - **User Guide**: `docs/user_guide.md` - **Deployment Guide**: `docs/deployment.md`