feat: Complete frontend integration with native WebSocket and FastAPI backend

- Created websocket_client.js: Native WebSocket wrapper with Socket.IO-compatible interface
  - Automatic reconnection with exponential backoff
  - Room-based subscriptions for targeted updates
  - Message queueing during disconnection

- Updated HTML templates (index.html, queue.html):
  - Replaced Socket.IO CDN with native websocket_client.js
  - No external dependencies needed

- Updated JavaScript files (app.js, queue.js):
  - Added room subscriptions on WebSocket connect (scan_progress, download_progress, downloads)
  - Added dual event handlers for backward compatibility
  - Support both old (scan_completed) and new (scan_complete) message types
  - Support both old (download_error) and new (download_failed) message types
  - Support both old (queue_updated) and new (queue_status) message types

- Registered anime router in fastapi_app.py:
  - Added anime_router import and registration
  - All API routers now properly included

- Documentation:
  - Created FRONTEND_INTEGRATION.md with comprehensive integration guide
  - Updated infrastructure.md with frontend integration section
  - Updated instructions.md to mark task as completed

- Testing:
  - Verified anime endpoint tests pass (pytest)
  - API endpoint mapping documented
  - WebSocket message format changes documented

Benefits:
  - Native WebSocket API (faster, smaller footprint)
  - No external CDN dependencies
  - Full backward compatibility with existing code
  - Proper integration with backend services
  - Real-time updates via room-based messaging
This commit is contained in:
2025-10-17 12:12:47 +02:00
parent 99e24a2fc3
commit 8f7c489bd2
9 changed files with 809 additions and 21 deletions

View File

@@ -133,9 +133,20 @@ class AniWorldApp {
initSocket() {
this.socket = io();
// Handle initial connection message from server
this.socket.on('connected', (data) => {
console.log('WebSocket connection confirmed', data);
});
this.socket.on('connect', () => {
this.isConnected = true;
console.log('Connected to server');
// Subscribe to rooms for targeted updates
this.socket.join('scan_progress');
this.socket.join('download_progress');
this.socket.join('downloads');
this.showToast(this.localization.getText('connected-server'), 'success');
this.updateConnectionStatus();
this.checkProcessLocks();
@@ -158,18 +169,24 @@ class AniWorldApp {
this.updateStatus(`Scanning: ${data.folder} (${data.counter})`);
});
this.socket.on('scan_completed', () => {
// Handle both 'scan_completed' (legacy) and 'scan_complete' (new backend)
const handleScanComplete = () => {
this.hideStatus();
this.showToast('Scan completed successfully', 'success');
this.updateProcessStatus('rescan', false);
this.loadSeries();
});
};
this.socket.on('scan_completed', handleScanComplete);
this.socket.on('scan_complete', handleScanComplete);
this.socket.on('scan_error', (data) => {
// Handle both 'scan_error' (legacy) and 'scan_failed' (new backend)
const handleScanError = (data) => {
this.hideStatus();
this.showToast(`Scan error: ${data.message}`, 'error');
this.showToast(`Scan error: ${data.message || data.error}`, 'error');
this.updateProcessStatus('rescan', false, true);
});
};
this.socket.on('scan_error', handleScanError);
this.socket.on('scan_failed', handleScanError);
// Scheduled scan events
this.socket.on('scheduled_rescan_started', () => {