/** * Watchlist UI functions */ /** * Display watchlist items */ async function displayWatchlist(status = null) { const container = document.getElementById('watchlistContainer'); if (!container) return; try { container.innerHTML = '
Chargement de la watchlist...
'; const items = await getWatchlist(status); const stats = await getWatchlistStats(); if (items.length === 0) { container.innerHTML = `

Aucun anime dans votre watchlist

Ajoutez des animes depuis la recherche pour commencer le suivi automatique

`; return; } // Render stats let statsHtml = ''; if (stats && stats.total > 0) { statsHtml = `
${stats.total}
Total
${stats.active}
Actifs
${stats.paused}
En pause
${stats.completed}
Terminés
`; } // Render items let itemsHtml = ''; items.forEach(item => { const statusIcon = getStatusIcon(item.status); const statusBadge = getStatusBadge(item.status); const lastEpInfo = item.last_episode_downloaded > 0 ? `Dernier épisode: ${item.last_episode_downloaded}` : ''; itemsHtml += `

${escapeHtml(item.anime_title)}

${statusBadge}
${statusIcon} ${item.provider_id} • ${item.lang.toUpperCase()}
${lastEpInfo ? `
${lastEpInfo}
` : ''} ${item.last_checked ? `
Dernière vérification: ${new Date(item.last_checked).toLocaleString('fr-FR')}
` : '
Jamais vérifié
'}
${item.status === 'active' && item.auto_download ? ` ` : item.status === 'paused' ? ` ` : ''}
${item.synopsis ? `
📖 Synopsis

${escapeHtml(item.synopsis)}

` : ''}
`; }); container.innerHTML = statsHtml + itemsHtml; } catch (error) { console.error('Error loading watchlist:', error); container.innerHTML = `
❌ Erreur lors du chargement: ${error.message}
`; } } /** * Get status icon */ function getStatusIcon(status) { const icons = { 'active': '✅', 'paused': '⏸️', 'completed': '✨', 'archived': '📦' }; return icons[status] || '📌'; } /** * Get status badge */ function getStatusBadge(status) { const badges = { 'active': 'Actif', 'paused': 'En pause', 'completed': 'Terminé', 'archived': 'Archivé' }; return badges[status] || ''; } /** * Add anime to watchlist from search results */ async function handleAddToWatchlist(animeUrl, providerId) { try { // Get anime details from the DOM or API const response = await fetch(`${API_BASE}/anime/metadata?url=${encodeURIComponent(animeUrl)}`); if (!response.ok) { throw new Error('Failed to fetch anime details'); } const data = await response.json(); const metadata = data.metadata || {}; // Extract anime title from URL if not in metadata let animeTitle = metadata.title || 'Unknown Anime'; if (animeTitle === 'Unknown Anime' || !animeTitle) { // Decode URL first if it's encoded let decodedUrl = animeUrl; try { decodedUrl = decodeURIComponent(animeUrl); } catch (e) {} // Try to extract title from URL try { const urlParts = decodedUrl.split('/'); // Find the anime name (usually between /catalogue/ and /saison/ or /vostfr/) const catalogueIndex = urlParts.indexOf('catalogue'); if (catalogueIndex >= 0 && urlParts[catalogueIndex + 1]) { animeTitle = urlParts[catalogueIndex + 1]; } else { // Fallback: use last part animeTitle = urlParts[urlParts.length - 2] || urlParts[urlParts.length - 1]; } animeTitle = animeTitle.replace(/-/g, ' ').replace(/\+/g, ' ').replace(/\s+/g, ' ').trim(); // Capitalize words animeTitle = animeTitle.replace(/\b\w/g, l => l.toUpperCase()); } catch (e) { console.warn('Could not extract title from URL:', e); } } const itemData = { anime_title: animeTitle, anime_url: animeUrl, provider_id: providerId, lang: 'vostfr', auto_download: true, quality_preference: 'auto', poster_image: metadata.poster_image || null, cover_image: metadata.cover_image || null, synopsis: metadata.synopsis || null, genres: metadata.genres || [] }; const result = await addToWatchlist(itemData); // Trigger download of all episodes immediately try { const token = localStorage.getItem('auth_token'); const downloadResponse = await fetch(`${API_BASE}/watchlist/${result.id}/download-all`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); if (downloadResponse.ok) { const downloadResult = await downloadResponse.json(); alert(`✅ "${result.anime_title}" a été ajouté et le téléchargement de tous les épisodes a commencé!\n\nVous recevrez automatiquement les nouveaux épisodes.`); } else { // Still show success even if download failed alert(`✅ "${result.anime_title}" a été ajouté à votre watchlist!\n\nLe téléchargement automatique des nouveaux épisodes est activé.`); } } catch (downloadError) { console.warn('Auto-download trigger failed:', downloadError); alert(`✅ "${result.anime_title}" a été ajouté à votre watchlist!\n\nLe téléchargement automatique des nouveaux épisodes est activé.`); } // Update button to show it's already in watchlist updateAddButton(animeUrl, true); } catch (error) { console.error('Error adding to watchlist:', error); alert(`❌ Erreur: ${error.message}`); } } /** * Update add button state */ function updateAddButton(animeUrl, isInWatchlist) { // Find all buttons for this anime const buttons = document.querySelectorAll(`[data-watchlist-url="${encodeURIComponent(animeUrl)}"]`); buttons.forEach(button => { if (isInWatchlist) { button.innerHTML = '✓ Suivi'; button.disabled = true; button.style.opacity = '0.6'; } else { button.innerHTML = '+ Suivre'; button.disabled = false; button.style.opacity = '1'; } }); } /** * Pause watchlist item */ async function handlePauseWatchlist(itemId) { try { await pauseWatchlistItem(itemId); await displayWatchlist(); alert('✅ Anime mis en pause'); } catch (error) { console.error('Error pausing item:', error); alert(`❌ Erreur: ${error.message}`); } } /** * Resume watchlist item */ async function handleResumeWatchlist(itemId) { try { await resumeWatchlistItem(itemId); await displayWatchlist(); alert('✅ Anime réactivé'); } catch (error) { console.error('Error resuming item:', error); alert(`❌ Erreur: ${error.message}`); } } /** * Check specific item */ async function handleCheckItem(itemId) { const button = event.target; const originalText = button.innerHTML; try { button.disabled = true; button.innerHTML = '⏳...'; const result = await checkWatchlistItem(itemId); if (result.new_episodes_found > 0) { alert(`🎉 ${result.new_episodes_found} nouveau(x) épisode(s) trouvé(s)!\n\n${result.episodes_downloaded.length} téléchargé(s)`); } else { alert('ℹ️ Aucun nouvel épisode trouvé'); } await displayWatchlist(); } catch (error) { console.error('Error checking item:', error); alert(`❌ Erreur: ${error.message}`); } finally { button.disabled = false; button.innerHTML = originalText; } } /** * Delete watchlist item */ async function handleDeleteWatchlist(itemId) { if (!confirm('⚠️ Êtes-vous sûr de vouloir supprimer cet anime de votre watchlist ?')) { return; } try { await deleteFromWatchlist(itemId); await displayWatchlist(); alert('✅ Anime supprimé de la watchlist'); } catch (error) { console.error('Error deleting item:', error); alert(`❌ Erreur: ${error.message}`); } } /** * Check all items */ async function handleCheckAll() { const button = event.target; const originalText = button.innerHTML; try { button.disabled = true; button.innerHTML = '⏳ Vérification...'; const result = await checkAllWatchlistItems(); alert(`✅ Vérification terminée!\n\n${result.checked} animes vérifiés\n${result.total_new_episodes} nouveaux épisodes trouvés\n${result.total_downloaded} téléchargés`); await displayWatchlist(); } catch (error) { console.error('Error checking all:', error); alert(`❌ Erreur: ${error.message}`); } finally { button.disabled = false; button.innerHTML = originalText; } } /** * Create settings modal HTML */ function createSettingsModal(settings) { const modalHtml = `

⚙️ Paramètres Watchlist

Entre 1 et 168 heures (1 semaine)

📥 Téléchargement automatique

Télécharger automatiquement les nouveaux épisodes

Maximum 5 téléchargements en parallèle

🔔 Notifications

Être notifié des nouveaux épisodes

`; return modalHtml; } /** * Close settings modal */ function closeSettingsModal() { const modal = document.getElementById('settingsModal'); if (modal) { modal.remove(); } } /** * Save settings */ async function saveSettings() { try { const checkInterval = parseInt(document.getElementById('checkInterval').value); const autoDownloadEnabled = document.getElementById('autoDownloadEnabled').checked; const maxConcurrent = parseInt(document.getElementById('maxConcurrent').value); const notifyEnabled = document.getElementById('notifyEnabled').checked; const settings = { check_interval_hours: checkInterval, auto_download_enabled: autoDownloadEnabled, max_concurrent_auto_downloads: maxConcurrent, notify_on_new_episodes: notifyEnabled }; await updateWatchlistSettings(settings); // Restart scheduler if it's running to apply new interval const status = await getSchedulerStatus(); if (status.running) { await stopScheduler(); await startScheduler(); } closeSettingsModal(); alert('✅ Paramètres enregistrés avec succès!'); await loadSchedulerStatus(); } catch (error) { console.error('Error saving settings:', error); alert(`❌ Erreur: ${error.message}`); } } // Make functions available globally window.displayWatchlist = displayWatchlist; window.handleAddToWatchlist = handleAddToWatchlist; window.handlePauseWatchlist = handlePauseWatchlist; window.handleResumeWatchlist = handleResumeWatchlist; window.handleCheckItem = handleCheckItem; window.handleDeleteWatchlist = handleDeleteWatchlist; window.handleCheckAll = handleCheckAll; window.createSettingsModal = createSettingsModal; window.closeSettingsModal = closeSettingsModal; window.saveSettings = saveSettings;