1const API_KEY = '603b3a029ec4f3222d788b8de4945dba'; 2let currentPage = 1; 3let currentGenre = ''; 4let currentYear = ''; 5let currentSort = 'popularity.desc'; 6let isLoading = false; 7 8document.addEventListener('DOMContentLoaded', () => { 9 initializeFilters(); 10 loadTVShows(); 11 setupLoadMore(); 12}); 13 14async function initializeFilters() { 15 // Load genres 16 try { 17 const response = await fetch(`https://api.themoviedb.org/3/genre/tv/list?api_key=${API_KEY}`); 18 const data = await response.json(); 19 const genreSelect = document.getElementById('genre-filter'); 20 21 data.genres.forEach(genre => { 22 const option = document.createElement('option'); 23 option.value = genre.id; 24 option.textContent = genre.name; 25 option.className = 'dark-option'; 26 genreSelect.appendChild(option); 27 }); 28 } catch (error) { 29 console.error('Error loading genres:', error); 30 } 31 32 // Generate years (current year - 50 years) 33 const yearSelect = document.getElementById('year-filter'); 34 const currentYear = new Date().getFullYear(); 35 for (let year = currentYear; year >= currentYear - 50; year--) { 36 const option = document.createElement('option'); 37 option.value = year; 38 option.textContent = year; 39 option.className = 'dark-option'; 40 yearSelect.appendChild(option); 41 } 42 43 // Add dark option class to sort filter options 44 document.querySelectorAll('#sort-filter option').forEach(option => { 45 option.className = 'dark-option'; 46 }); 47 48 // Add event listeners 49 document.getElementById('genre-filter').addEventListener('change', handleFilterChange); 50 document.getElementById('year-filter').addEventListener('change', handleFilterChange); 51 document.getElementById('sort-filter').addEventListener('change', handleFilterChange); 52} 53 54function handleFilterChange() { 55 currentGenre = document.getElementById('genre-filter').value; 56 currentYear = document.getElementById('year-filter').value; 57 currentSort = document.getElementById('sort-filter').value; 58 currentPage = 1; 59 loadTVShows(true); 60} 61 62async function loadTVShows(reset = false) { 63 if (isLoading) return; 64 isLoading = true; 65 66 const tvShowsGrid = document.querySelector('.movies-grid'); 67 if (reset) { 68 tvShowsGrid.innerHTML = '<div class="loading">Loading TV shows...</div>'; 69 } 70 71 try { 72 let url = `https://api.themoviedb.org/3/discover/tv?api_key=${API_KEY}&language=en-US&page=${currentPage}&sort_by=${currentSort}`; 73 74 if (currentGenre) { 75 url += `&with_genres=${currentGenre}`; 76 } 77 if (currentYear) { 78 url += `&first_air_date_year=${currentYear}`; 79 } 80 81 const response = await fetch(url); 82 const data = await response.json(); 83 84 if (reset) { 85 tvShowsGrid.innerHTML = ''; 86 } 87 88 data.results.forEach(show => { 89 const showCard = document.createElement('div'); 90 showCard.className = 'movie-card'; 91 showCard.innerHTML = ` 92 <div class="card-image"> 93 <img src="https://image.tmdb.org/t/p/w342${show.poster_path}" width="342" height="513" 94 loading="lazy" decoding="async" 95 alt="${show.name}" 96 onerror="this.src='placeholder.jpg'"> 97 <div class="card-overlay"> 98 <div class="rating"> 99 <i class="fas fa-star"></i> 100 <span>${show.vote_average.toFixed(1)}</span> 101 </div> 102 <p>${show.overview ? show.overview.slice(0, 100) + '...' : 'No overview available'}</p> 103 </div> 104 </div> 105 <div class="card-info"> 106 <h4>${show.name}</h4> 107 <div class="meta"> 108 <span>${show.first_air_date ? show.first_air_date.split('-')[0] : 'N/A'}</span> 109 <span>${show.original_language.toUpperCase()}</span> 110 </div> 111 </div> 112 `; 113 114 showCard.addEventListener('click', () => { 115 window.location.href = `/details?id=${show.id}&type=tv`; 116 }); 117 118 tvShowsGrid.appendChild(showCard); 119 }); 120 121 isLoading = false;
122 document.getElementById('load-more-btn').style.display = 123 currentPage >= data.total_pages ? 'none' : 'inline-block'; 124 125 } catch (error) { 126 console.error('Error loading TV shows:', error); 127 if (reset) { 128 tvShowsGrid.innerHTML = '<div class="error">Error loading TV shows. Please try again later.</div>'; 129 } 130 isLoading = false; 131 } 132} 133 134function setupLoadMore() { 135 const loadMoreBtn = document.getElementById('load-more-btn'); 136 loadMoreBtn.addEventListener('click', () => { 137 currentPage++; 138 loadTVShows(); 139 }); 140}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.