/** * AniWorld - Queue Page Application Initializer * * Main entry point for the queue page. Initializes all modules. * * Dependencies: All shared and queue modules */ var AniWorld = window.AniWorld || {}; AniWorld.QueueApp = (function() { 'use strict'; /** * Initialize the queue page application */ async function init() { console.log('AniWorld Queue App initializing...'); // Check authentication first const isAuthenticated = await AniWorld.Auth.checkAuth(); if (!isAuthenticated) { return; // Auth module handles redirect } // Initialize theme AniWorld.Theme.init(); // Initialize WebSocket connection AniWorld.WebSocketClient.init(); // Initialize socket event handlers for this page AniWorld.QueueSocketHandler.init(AniWorld.QueueApp); // Bind UI events bindEvents(); // Load initial data await loadQueueData(); console.log('AniWorld Queue App initialized successfully'); } /** * Bind UI event handlers */ function bindEvents() { // Theme toggle const themeToggle = document.getElementById('theme-toggle'); if (themeToggle) { themeToggle.addEventListener('click', function() { AniWorld.Theme.toggle(); }); } // Queue management actions const clearCompletedBtn = document.getElementById('clear-completed-btn'); if (clearCompletedBtn) { clearCompletedBtn.addEventListener('click', function() { clearQueue('completed'); }); } const clearFailedBtn = document.getElementById('clear-failed-btn'); if (clearFailedBtn) { clearFailedBtn.addEventListener('click', function() { clearQueue('failed'); }); } const clearPendingBtn = document.getElementById('clear-pending-btn'); if (clearPendingBtn) { clearPendingBtn.addEventListener('click', function() { clearQueue('pending'); }); } const retryAllBtn = document.getElementById('retry-all-btn'); if (retryAllBtn) { retryAllBtn.addEventListener('click', retryAllFailed); } // Download controls const startQueueBtn = document.getElementById('start-queue-btn'); if (startQueueBtn) { startQueueBtn.addEventListener('click', startDownload); } const stopQueueBtn = document.getElementById('stop-queue-btn'); if (stopQueueBtn) { stopQueueBtn.addEventListener('click', stopDownloads); } // Modal events const closeConfirm = document.getElementById('close-confirm'); if (closeConfirm) { closeConfirm.addEventListener('click', AniWorld.UI.hideConfirmModal); } const confirmCancel = document.getElementById('confirm-cancel'); if (confirmCancel) { confirmCancel.addEventListener('click', AniWorld.UI.hideConfirmModal); } const modalOverlay = document.querySelector('#confirm-modal .modal-overlay'); if (modalOverlay) { modalOverlay.addEventListener('click', AniWorld.UI.hideConfirmModal); } // Logout functionality const logoutBtn = document.getElementById('logout-btn'); if (logoutBtn) { logoutBtn.addEventListener('click', function() { AniWorld.Auth.logout(AniWorld.UI.showToast); }); } } /** * Load queue data and update display */ async function loadQueueData() { const data = await AniWorld.QueueAPI.loadQueueData(); if (data) { AniWorld.QueueRenderer.updateQueueDisplay(data); AniWorld.ProgressHandler.processPendingProgressUpdates(); } } /** * Clear queue by type * @param {string} type - 'completed', 'failed', or 'pending' */ async function clearQueue(type) { const titles = { completed: 'Clear Completed Downloads', failed: 'Clear Failed Downloads', pending: 'Remove All Pending Downloads' }; const messages = { completed: 'Are you sure you want to clear all completed downloads?', failed: 'Are you sure you want to clear all failed downloads?', pending: 'Are you sure you want to remove all pending downloads from the queue?' }; const confirmed = await AniWorld.UI.showConfirmModal(titles[type], messages[type]); if (!confirmed) return; try { let data; if (type === 'completed') { data = await AniWorld.QueueAPI.clearCompleted(); AniWorld.UI.showToast('Cleared ' + (data?.count || 0) + ' completed downloads', 'success'); } else if (type === 'failed') { data = await AniWorld.QueueAPI.clearFailed(); AniWorld.UI.showToast('Cleared ' + (data?.count || 0) + ' failed downloads', 'success'); } else if (type === 'pending') { data = await AniWorld.QueueAPI.clearPending(); AniWorld.UI.showToast('Removed ' + (data?.count || 0) + ' pending downloads', 'success'); } await loadQueueData(); } catch (error) { console.error('Error clearing queue:', error); AniWorld.UI.showToast('Failed to clear queue', 'error'); } } /** * Retry a failed download * @param {string} downloadId - Download item ID */ async function retryDownload(downloadId) { try { const data = await AniWorld.QueueAPI.retryDownloads([downloadId]); AniWorld.UI.showToast('Retried ' + (data?.retried_count || 1) + ' download(s)', 'success'); await loadQueueData(); } catch (error) { console.error('Error retrying download:', error); AniWorld.UI.showToast('Failed to retry download', 'error'); } } /** * Retry all failed downloads */ async function retryAllFailed() { const confirmed = await AniWorld.UI.showConfirmModal( 'Retry All Failed Downloads', 'Are you sure you want to retry all failed downloads?' ); if (!confirmed) return; try { // Get all failed download IDs const failedCards = document.querySelectorAll('#failed-downloads .download-card.failed'); const itemIds = Array.from(failedCards).map(function(card) { return card.dataset.id; }).filter(function(id) { return id; }); if (itemIds.length === 0) { AniWorld.UI.showToast('No failed downloads to retry', 'info'); return; } const data = await AniWorld.QueueAPI.retryDownloads(itemIds); AniWorld.UI.showToast('Retried ' + (data?.retried_count || itemIds.length) + ' download(s)', 'success'); await loadQueueData(); } catch (error) { console.error('Error retrying failed downloads:', error); AniWorld.UI.showToast('Failed to retry downloads', 'error'); } } /** * Remove item from queue * @param {string} downloadId - Download item ID */ async function removeFromQueue(downloadId) { try { const success = await AniWorld.QueueAPI.removeFromQueue(downloadId); if (success) { AniWorld.UI.showToast('Download removed from queue', 'success'); await loadQueueData(); } else { AniWorld.UI.showToast('Failed to remove from queue', 'error'); } } catch (error) { console.error('Error removing from queue:', error); AniWorld.UI.showToast('Failed to remove from queue', 'error'); } } /** * Start queue processing */ async function startDownload() { try { const data = await AniWorld.QueueAPI.startQueue(); if (data && data.status === 'success') { AniWorld.UI.showToast('Queue processing started - all items will download automatically', 'success'); // Update UI document.getElementById('start-queue-btn').style.display = 'none'; document.getElementById('stop-queue-btn').style.display = 'inline-flex'; document.getElementById('stop-queue-btn').disabled = false; await loadQueueData(); } else { AniWorld.UI.showToast('Failed to start queue: ' + (data?.message || 'Unknown error'), 'error'); } } catch (error) { console.error('Error starting queue:', error); AniWorld.UI.showToast('Failed to start queue processing', 'error'); } } /** * Stop queue processing */ async function stopDownloads() { try { const data = await AniWorld.QueueAPI.stopQueue(); if (data && data.status === 'success') { AniWorld.UI.showToast('Queue processing stopped', 'success'); // Update UI document.getElementById('stop-queue-btn').style.display = 'none'; document.getElementById('start-queue-btn').style.display = 'inline-flex'; document.getElementById('start-queue-btn').disabled = false; await loadQueueData(); } else { AniWorld.UI.showToast('Failed to stop queue: ' + (data?.message || 'Unknown error'), 'error'); } } catch (error) { console.error('Error stopping queue:', error); AniWorld.UI.showToast('Failed to stop queue', 'error'); } } // Public API return { init: init, loadQueueData: loadQueueData, retryDownload: retryDownload, removeFromQueue: removeFromQueue, startDownload: startDownload, stopDownloads: stopDownloads }; })(); // Initialize the application when DOM is loaded document.addEventListener('DOMContentLoaded', function() { AniWorld.QueueApp.init(); }); // Expose for inline event handlers (backwards compatibility) window.queueManager = { retryDownload: function(id) { return AniWorld.QueueApp.retryDownload(id); }, removeFromQueue: function(id) { return AniWorld.QueueApp.removeFromQueue(id); }, removeFailedDownload: function(id) { return AniWorld.QueueApp.removeFromQueue(id); } };