use of websockets

This commit is contained in:
2025-11-01 19:23:32 +01:00
parent 57c30a0156
commit d5f7b1598f
5 changed files with 131 additions and 100 deletions

View File

@@ -14,8 +14,9 @@ class QueueManager {
this.initSocket();
this.bindEvents();
this.initTheme();
this.startRefreshTimer();
this.loadQueueData();
// Remove polling - use WebSocket events for real-time updates
// this.startRefreshTimer(); // ← REMOVED
this.loadQueueData(); // Load initial data once
}
initSocket() {
@@ -54,24 +55,22 @@ class QueueManager {
}
});
this.socket.on('download_progress_update', (data) => {
// Progress updates trigger a data reload to refresh the UI
this.loadQueueData();
});
// Download queue events
this.socket.on('download_started', () => {
this.showToast('Download queue started', 'success');
this.loadQueueData(); // Refresh data
// Full reload needed - queue structure changed
this.loadQueueData();
});
this.socket.on('queue_started', () => {
this.showToast('Download queue started', 'success');
this.loadQueueData(); // Refresh data
// Full reload needed - queue structure changed
this.loadQueueData();
});
this.socket.on('download_progress', (data) => {
// Progress updates trigger a data reload to refresh the UI
this.loadQueueData();
// Update progress in real-time without reloading all data
console.log('Received download progress:', data);
this.updateDownloadProgress(data);
});
// Handle both old and new download completion events
@@ -79,7 +78,8 @@ class QueueManager {
const serieName = data.serie_name || data.serie || 'Unknown';
const episode = data.episode || '';
this.showToast(`Completed: ${serieName}${episode ? ' - Episode ' + episode : ''}`, 'success');
this.loadQueueData(); // Refresh data
// Full reload needed - item moved from active to completed
this.loadQueueData();
};
this.socket.on('download_completed', handleDownloadComplete);
this.socket.on('download_complete', handleDownloadComplete);
@@ -88,19 +88,22 @@ class QueueManager {
const handleDownloadError = (data) => {
const message = data.error || data.message || 'Unknown error';
this.showToast(`Download failed: ${message}`, 'error');
this.loadQueueData(); // Refresh data
// Full reload needed - item moved from active to failed
this.loadQueueData();
};
this.socket.on('download_error', handleDownloadError);
this.socket.on('download_failed', handleDownloadError);
this.socket.on('download_queue_completed', () => {
this.showToast('All downloads completed!', 'success');
this.loadQueueData(); // Refresh data
// Full reload needed - queue state changed
this.loadQueueData();
});
this.socket.on('queue_completed', () => {
this.showToast('All downloads completed!', 'success');
this.loadQueueData(); // Refresh data
// Full reload needed - queue state changed
this.loadQueueData();
});
this.socket.on('download_stop_requested', () => {
@@ -110,7 +113,8 @@ class QueueManager {
// Handle both old and new queue stopped events
const handleQueueStopped = () => {
this.showToast('Download queue stopped', 'success');
this.loadQueueData(); // Refresh data
// Full reload needed - queue state changed
this.loadQueueData();
};
this.socket.on('download_stopped', handleQueueStopped);
this.socket.on('queue_stopped', handleQueueStopped);
@@ -118,11 +122,13 @@ class QueueManager {
// Handle queue paused/resumed
this.socket.on('queue_paused', () => {
this.showToast('Queue paused', 'info');
// Full reload needed - queue state changed
this.loadQueueData();
});
this.socket.on('queue_resumed', () => {
this.showToast('Queue resumed', 'success');
// Full reload needed - queue state changed
this.loadQueueData();
});
}
@@ -273,6 +279,91 @@ class QueueManager {
}
}
/**
* Update download progress in real-time
* @param {Object} data - Progress data from WebSocket
*/
updateDownloadProgress(data) {
console.log('updateDownloadProgress called with:', JSON.stringify(data, null, 2));
// Extract download ID - handle different data structures
let downloadId = data.id || data.download_id || data.item_id;
// Check if data is wrapped in another 'data' property
if (!downloadId && data.data) {
downloadId = data.data.id || data.data.download_id || data.data.item_id;
data = data.data; // Use nested data
}
// Also try metadata.item_id as fallback
if (!downloadId && data.metadata && data.metadata.item_id) {
downloadId = data.metadata.item_id;
}
if (!downloadId) {
console.warn('No download ID in progress data');
console.warn('Data structure:', data);
console.warn('Available keys:', Object.keys(data));
return;
}
// Find the download card in active downloads
const card = document.querySelector(`[data-download-id="${downloadId}"]`);
if (!card) {
// Card not found - might need to reload queue to get new active download
console.log(`Download card not found for ID: ${downloadId}, reloading queue`);
this.loadQueueData();
return;
}
// Extract progress information - handle both ProgressService and yt-dlp formats
const progress = data.progress || data;
const percent = progress.percent || 0;
// Check if we have detailed yt-dlp progress (downloaded_mb, total_mb, speed_mbps)
// or basic ProgressService progress (current, total)
let downloaded, total, speed;
if (progress.downloaded_mb !== undefined && progress.total_mb !== undefined) {
// yt-dlp detailed format
downloaded = progress.downloaded_mb.toFixed(1);
total = progress.total_mb.toFixed(1);
speed = progress.speed_mbps ? progress.speed_mbps.toFixed(1) : '0.0';
} else if (progress.current !== undefined && progress.total !== undefined) {
// ProgressService basic format - convert bytes to MB
downloaded = (progress.current / (1024 * 1024)).toFixed(1);
total = progress.total > 0 ? (progress.total / (1024 * 1024)).toFixed(1) : 'Unknown';
speed = '0.0'; // Speed not available in basic format
} else {
// Fallback
downloaded = '0.0';
total = 'Unknown';
speed = '0.0';
}
// Update progress bar
const progressFill = card.querySelector('.progress-fill');
if (progressFill) {
progressFill.style.width = `${percent}%`;
}
// Update progress text
const progressInfo = card.querySelector('.progress-info');
if (progressInfo) {
const percentSpan = progressInfo.querySelector('span:first-child');
const speedSpan = progressInfo.querySelector('.download-speed');
if (percentSpan) {
percentSpan.textContent = `${percent.toFixed(1)}% (${downloaded} MB / ${total} MB)`;
}
if (speedSpan) {
speedSpan.textContent = `${speed} MB/s`;
}
}
console.log(`Updated progress for ${downloadId}: ${percent.toFixed(1)}%`);
}
renderActiveDownloads(downloads) {
const container = document.getElementById('active-downloads');
@@ -297,7 +388,7 @@ class QueueManager {
const total = progress.total_mb ? `${progress.total_mb.toFixed(1)} MB` : 'Unknown';
return `
<div class="download-card active">
<div class="download-card active" data-download-id="${download.id}">
<div class="download-header">
<div class="download-info">
<h4>${this.escapeHtml(download.serie_name)}</h4>

View File

@@ -102,6 +102,8 @@ class WebSocketClient {
const message = JSON.parse(data);
const { type, data: payload, timestamp } = message;
console.log(`WebSocket message: type=${type}`, payload);
// Emit event with payload
if (type) {
this.emit(type, payload || {});