/** * Watchlist management and auto-download UI * Note: API_BASE is defined in api.js (loaded before this file) */ /** * Get user's watchlist */ async function getWatchlist(status = null) { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } let url = `${API_BASE}/watchlist`; if (status) { url += `?status=${status}`; } const response = await fetch(url, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch watchlist'); } return await response.json(); } /** * Add anime to watchlist */ async function addToWatchlist(animeData) { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(animeData) }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to add to watchlist'); } return await response.json(); } /** * Update watchlist item */ async function updateWatchlistItem(itemId, updateData) { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/${itemId}`, { method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(updateData) }); if (!response.ok) { throw new Error('Failed to update watchlist item'); } return await response.json(); } /** * Delete from watchlist */ async function deleteFromWatchlist(itemId) { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/${itemId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to delete from watchlist'); } return await response.json(); } /** * Pause watchlist item */ async function pauseWatchlistItem(itemId) { return await updateWatchlistItem(itemId, { status: 'paused' }); } /** * Resume watchlist item */ async function resumeWatchlistItem(itemId) { return await updateWatchlistItem(itemId, { status: 'active' }); } /** * Check specific anime for new episodes */ async function checkWatchlistItem(itemId) { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/${itemId}/check`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to check for new episodes'); } return await response.json(); } /** * Check all watchlist items */ async function checkAllWatchlistItems() { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/check-all`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to check all items'); } return await response.json(); } /** * Get watchlist settings */ async function getWatchlistSettings() { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/settings`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch settings'); } return await response.json(); } /** * Update watchlist settings */ async function updateWatchlistSettings(settings) { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/settings`, { method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(settings) }); if (!response.ok) { throw new Error('Failed to update settings'); } return await response.json(); } /** * Get watchlist statistics */ async function getWatchlistStats() { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/stats`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch statistics'); } return await response.json(); } /** * Get scheduler status */ async function getSchedulerStatus() { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/scheduler/status`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch scheduler status'); } return await response.json(); } /** * Start scheduler */ async function startScheduler() { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/scheduler/start`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to start scheduler'); } return await response.json(); } /** * Stop scheduler */ async function stopScheduler() { const token = getToken(); if (!token) { throw new Error('Not authenticated'); } const response = await fetch(`${API_BASE}/watchlist/scheduler/stop`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to stop scheduler'); } return await response.json(); } // Make functions available globally window.getWatchlist = getWatchlist; window.addToWatchlist = addToWatchlist; window.updateWatchlistItem = updateWatchlistItem; window.deleteFromWatchlist = deleteFromWatchlist; window.pauseWatchlistItem = pauseWatchlistItem; window.resumeWatchlistItem = resumeWatchlistItem; window.checkWatchlistItem = checkWatchlistItem; window.checkAllWatchlistItems = checkAllWatchlistItems; window.getWatchlistSettings = getWatchlistSettings; window.updateWatchlistSettings = updateWatchlistSettings; window.getWatchlistStats = getWatchlistStats; window.getSchedulerStatus = getSchedulerStatus; window.startScheduler = startScheduler; window.stopScheduler = stopScheduler; /** * Current filter state */ let currentFilter = 'all'; /** * Filter watchlist */ async function filterWatchlist(status, tabElement) { currentFilter = status; // Update tab styles document.querySelectorAll('.filter-tab').forEach(tab => { tab.classList.remove('active'); }); tabElement.classList.add('active'); // Reload with filter await displayWatchlist(status === 'all' ? null : status); } /** * Handle start scheduler */ async function handleStartScheduler() { try { await startScheduler(); await loadSchedulerStatus(); alert('✅ Planificateur démarré!'); } catch (error) { console.error('Error starting scheduler:', error); alert(`❌ Erreur: ${error.message}`); } } /** * Handle stop scheduler */ async function handleStopScheduler() { try { await stopScheduler(); await loadSchedulerStatus(); alert('✅ Planificateur arrêté!'); } catch (error) { console.error('Error stopping scheduler:', error); alert(`❌ Erreur: ${error.message}`); } } /** * Handle check all */ async function handleCheckAll() { try { await checkAllWatchlistItems(); await loadSchedulerStatus(); } catch (error) { console.error('Error checking all:', error); alert(`❌ Erreur: ${error.message}`); } } /** * Handle open settings */ async function handleOpenSettings() { try { const settings = await getWatchlistSettings(); const modalHtml = createSettingsModal(settings); // Add modal to body const modalContainer = document.createElement('div'); modalContainer.innerHTML = modalHtml; document.body.appendChild(modalContainer); } catch (error) { console.error('Error loading settings:', error); alert(`❌ Erreur: ${error.message}`); } } // Make functions available globally window.filterWatchlist = filterWatchlist; window.handleStartScheduler = handleStartScheduler; window.handleStopScheduler = handleStopScheduler; window.handleCheckAll = handleCheckAll; window.handleOpenSettings = handleOpenSettings; /** * Load scheduler status */ async function loadSchedulerStatus() { try { const status = await getSchedulerStatus(); updateSchedulerUI(status); } catch (error) { console.error('Error loading scheduler status:', error); } } /** * Update scheduler UI */ function updateSchedulerUI(status) { const startBtn = document.getElementById('startSchedulerBtn'); const stopBtn = document.getElementById('stopSchedulerBtn'); const nextRunInfo = document.getElementById('nextRunInfo'); // nextRunInfo is required, but buttons are optional if (!nextRunInfo) { console.warn('nextRunInfo element not found'); return; } if (status.running) { // Update buttons if they exist if (startBtn) startBtn.style.display = 'none'; if (stopBtn) stopBtn.style.display = 'inline-block'; if (status.next_run) { const nextRun = new Date(status.next_run); nextRunInfo.innerHTML = `✓ En cours
Prochaine vérification: ${nextRun.toLocaleString('fr-FR')}`; } else { // Scheduler running but no next_run yet (just started) const interval = status.settings?.check_interval_hours || 6; nextRunInfo.innerHTML = `✓ En cours
Vérification toutes les ${interval}h`; } } else { // Update buttons if they exist if (startBtn) startBtn.style.display = 'inline-block'; if (stopBtn) stopBtn.style.display = 'none'; nextRunInfo.innerHTML = '⏸️ Arrêté'; } } window.loadSchedulerStatus = loadSchedulerStatus; window.updateSchedulerUI = updateSchedulerUI; window.filterWatchlist = filterWatchlist; window.handleStartScheduler = handleStartScheduler; window.handleStopScheduler = handleStopScheduler; window.handleCheckAll = handleCheckAll; window.handleOpenSettings = handleOpenSettings;