x
This commit is contained in:
parent
61a1b08280
commit
c8b022f3c0
1 changed files with 541 additions and 70 deletions
611
index.html
611
index.html
|
|
@ -422,7 +422,7 @@
|
|||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.category-item img:hover {
|
||||
.category-item:hover img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
|
|
@ -457,6 +457,205 @@
|
|||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Movie details modal styles */
|
||||
.details-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
z-index: 1100;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.details-content {
|
||||
background-color: white;
|
||||
width: 90%;
|
||||
max-width: 900px;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dark-mode .details-content {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.night-light .details-content {
|
||||
background-color: #f5deb3;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.details-backdrop {
|
||||
position: relative;
|
||||
height: 300px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.backdrop-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 60%;
|
||||
background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.details-body {
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.details-close {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background-color: rgba(0,0,0,0.6);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.genre-tag {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
margin: 0 5px 5px 0;
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
border-radius: 20px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.dark-mode .genre-tag {
|
||||
background-color: rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.night-light .genre-tag {
|
||||
background-color: rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.watch-button {
|
||||
background-color: #32cd32;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.trailer-button {
|
||||
background-color: #ff6347;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.cast-section {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.cast-list {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.cast-item {
|
||||
flex: 0 0 auto;
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cast-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* Picture-in-picture trailer styles */
|
||||
.pip-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 300px;
|
||||
background-color: black;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
z-index: 1200;
|
||||
}
|
||||
|
||||
.pip-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.pip-title {
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.pip-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pip-video {
|
||||
width: 100%;
|
||||
height: 169px; /* 16:9 aspect ratio for 300px width */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="text-black">
|
||||
|
|
@ -672,28 +871,63 @@
|
|||
const movieTile = document.createElement('div');
|
||||
movieTile.className = 'movie-tile';
|
||||
movieTile.innerHTML = `
|
||||
<a href="javascript:void(0);" onclick="openModal('${mediaType}', '${id}')">
|
||||
<div class="relative">
|
||||
<img src="${posterPath}" alt="Poster for ${title}" style="width:100%; height:auto;" loading="lazy">
|
||||
<h3>${title}</h3>
|
||||
<p>${overview.substring(0, 100)}${overview.length > 100 ? '...' : ''}</p>
|
||||
</a>
|
||||
<button class="trailer-btn" onclick="fetchTrailer('${title}')">Trailer</button>
|
||||
<div class="media-label">${mediaType.toUpperCase()}</div>
|
||||
<div class="media-label">${mediaType.toUpperCase()}</div>
|
||||
${result.vote_average ? `<div class="rating-badge">${result.vote_average.toFixed(1)} ⭐</div>` : ''}
|
||||
</div>
|
||||
<h3>${title}</h3>
|
||||
<p>${overview.substring(0, 100)}${overview.length > 100 ? '...' : ''}</p>
|
||||
<div class="flex justify-between mt-3">
|
||||
<button class="watch-btn bg-green-500 hover:bg-green-600 text-white px-3 py-1 rounded text-sm" onclick="openModal('${mediaType}', '${id}')">Watch</button>
|
||||
<button class="info-btn bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded text-sm" onclick="openMovieDetails('${mediaType}', ${id})">Details</button>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(movieTile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchTrailer(title) {
|
||||
function fetchTrailer(title, movieId = null, mediaType = 'movie') {
|
||||
showProgress('Finding trailer...');
|
||||
const youtubeSearchUrl = `https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=${encodeURIComponent(title + ' trailer')}&key=${youtubeApiKey}`;
|
||||
|
||||
// If we have a movieId, get trailer directly from TMDB
|
||||
if (movieId) {
|
||||
const detailsUrl = `https://api.themoviedb.org/3/${mediaType}/${movieId}/videos?api_key=${apiKey}`;
|
||||
fetch(detailsUrl)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const trailer = data.results.find(video =>
|
||||
(video.type === 'Trailer' || video.type === 'Teaser') &&
|
||||
video.site === 'YouTube'
|
||||
);
|
||||
|
||||
if (trailer) {
|
||||
openTrailerInPictureInPicture(trailer.key, title);
|
||||
showProgress('Trailer loaded');
|
||||
} else {
|
||||
// Fall back to YouTube search if no trailer in TMDB
|
||||
searchYouTubeForTrailer(title);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching TMDB trailer:', error);
|
||||
// Fall back to YouTube search
|
||||
searchYouTubeForTrailer(title);
|
||||
});
|
||||
} else {
|
||||
searchYouTubeForTrailer(title);
|
||||
}
|
||||
}
|
||||
|
||||
function searchYouTubeForTrailer(title) {
|
||||
const youtubeSearchUrl = `https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=${encodeURIComponent(title + ' official trailer')}&key=${youtubeApiKey}`;
|
||||
fetch(youtubeSearchUrl)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.items && data.items.length > 0) {
|
||||
const videoId = data.items[0].id.videoId;
|
||||
openTrailerModal(videoId);
|
||||
openTrailerInPictureInPicture(videoId, title);
|
||||
showProgress('Trailer loaded');
|
||||
} else {
|
||||
alert('Trailer not found.');
|
||||
|
|
@ -706,6 +940,80 @@
|
|||
});
|
||||
}
|
||||
|
||||
function openTrailerInPictureInPicture(videoId, title) {
|
||||
// Remove any existing pip container
|
||||
const existingPip = document.querySelector('.pip-container');
|
||||
if (existingPip) {
|
||||
existingPip.remove();
|
||||
}
|
||||
|
||||
// Create the PiP container
|
||||
const pipContainer = document.createElement('div');
|
||||
pipContainer.className = 'pip-container';
|
||||
pipContainer.innerHTML = `
|
||||
<div class="pip-header">
|
||||
<div class="pip-title">Trailer: ${title}</div>
|
||||
<button class="pip-close">×</button>
|
||||
</div>
|
||||
<iframe class="pip-video" src="https://www.youtube.com/embed/${videoId}?autoplay=1" frameborder="0" allowfullscreen></iframe>
|
||||
`;
|
||||
|
||||
// Add to the DOM
|
||||
document.body.appendChild(pipContainer);
|
||||
|
||||
// Add event listener to close button
|
||||
const closeButton = pipContainer.querySelector('.pip-close');
|
||||
closeButton.addEventListener('click', () => {
|
||||
pipContainer.remove();
|
||||
});
|
||||
|
||||
// Make the PiP container draggable
|
||||
makeDraggable(pipContainer);
|
||||
}
|
||||
|
||||
function makeDraggable(element) {
|
||||
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
|
||||
const header = element.querySelector('.pip-header');
|
||||
|
||||
if (header) {
|
||||
header.onmousedown = dragMouseDown;
|
||||
} else {
|
||||
element.onmousedown = dragMouseDown;
|
||||
}
|
||||
|
||||
function dragMouseDown(e) {
|
||||
e = e || window.event;
|
||||
e.preventDefault();
|
||||
// Get the mouse cursor position at startup
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
document.onmouseup = closeDragElement;
|
||||
// Call function when mouse moves
|
||||
document.onmousemove = elementDrag;
|
||||
}
|
||||
|
||||
function elementDrag(e) {
|
||||
e = e || window.event;
|
||||
e.preventDefault();
|
||||
// Calculate the new cursor position
|
||||
pos1 = pos3 - e.clientX;
|
||||
pos2 = pos4 - e.clientY;
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
// Set the element's new position
|
||||
element.style.top = (element.offsetTop - pos2) + "px";
|
||||
element.style.left = (element.offsetLeft - pos1) + "px";
|
||||
element.style.right = "auto"; // Clear right position when dragging
|
||||
element.style.bottom = "auto"; // Clear bottom position when dragging
|
||||
}
|
||||
|
||||
function closeDragElement() {
|
||||
// Stop moving when mouse button is released
|
||||
document.onmouseup = null;
|
||||
document.onmousemove = null;
|
||||
}
|
||||
}
|
||||
|
||||
function openTrailerModal(videoId) {
|
||||
const videoUrl = `https://www.youtube.com/embed/${videoId}`;
|
||||
const modal = document.getElementById("videoModal");
|
||||
|
|
@ -727,6 +1035,133 @@
|
|||
document.title = title;
|
||||
}
|
||||
|
||||
// Detailed movie info modal
|
||||
async function openMovieDetails(mediaType, id) {
|
||||
try {
|
||||
showProgress('Loading details...');
|
||||
|
||||
// Remove any existing details modal
|
||||
const existingModal = document.getElementById('movieDetailsModal');
|
||||
if (existingModal) {
|
||||
existingModal.remove();
|
||||
}
|
||||
|
||||
// Fetch complete movie details with append_to_response to minimize API calls
|
||||
const url = `https://api.themoviedb.org/3/${mediaType}/${id}?api_key=${apiKey}&append_to_response=credits,videos,release_dates`;
|
||||
const response = await fetch(url);
|
||||
const movie = await response.json();
|
||||
|
||||
// Create the modal
|
||||
const detailsModal = document.createElement('div');
|
||||
detailsModal.className = 'details-modal';
|
||||
detailsModal.id = 'movieDetailsModal';
|
||||
|
||||
// Find a trailer if available
|
||||
const trailer = movie.videos?.results.find(video =>
|
||||
(video.type === 'Trailer' || video.type === 'Teaser') &&
|
||||
video.site === 'YouTube'
|
||||
);
|
||||
|
||||
// Get certification (rating)
|
||||
let certification = '';
|
||||
if (mediaType === 'movie' && movie.release_dates?.results) {
|
||||
const usReleases = movie.release_dates.results.find(country => country.iso_3166_1 === 'US');
|
||||
if (usReleases && usReleases.release_dates.length > 0) {
|
||||
certification = usReleases.release_dates.find(r => r.certification)?.certification || '';
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare content
|
||||
const title = movie.title || movie.name;
|
||||
const backdropPath = movie.backdrop_path ?
|
||||
`https://image.tmdb.org/t/p/w1280${movie.backdrop_path}` :
|
||||
(movie.poster_path ? `https://image.tmdb.org/t/p/w780${movie.poster_path}` : '');
|
||||
|
||||
detailsModal.innerHTML = `
|
||||
<div class="details-content">
|
||||
<div class="details-backdrop" style="background-image: url('${backdropPath}')">
|
||||
<button class="details-close">×</button>
|
||||
<div class="backdrop-overlay">
|
||||
<h1 class="text-white text-3xl font-bold">${title}</h1>
|
||||
<div class="flex flex-wrap mt-2">
|
||||
${movie.release_date ? `<span class="text-white mr-4">${new Date(movie.release_date).getFullYear()}</span>` : ''}
|
||||
${movie.runtime ? `<span class="text-white mr-4">${Math.floor(movie.runtime / 60)}h ${movie.runtime % 60}m</span>` : ''}
|
||||
${certification ? `<span class="text-white mr-4">${certification}</span>` : ''}
|
||||
${movie.vote_average ? `<span class="text-white mr-4">${movie.vote_average.toFixed(1)} ⭐</span>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="details-body">
|
||||
<div class="flex flex-wrap mb-4">
|
||||
${movie.genres.map(genre => `<span class="genre-tag">${genre.name}</span>`).join('')}
|
||||
</div>
|
||||
|
||||
<p class="mb-6">${movie.overview}</p>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button class="action-button watch-button" onclick="openModal('${mediaType}', ${id})">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Watch Now
|
||||
</button>
|
||||
${trailer ? `
|
||||
<button class="action-button trailer-button" onclick="openTrailerInPictureInPicture('${trailer.key}', '${title.replace(/'/g, "\\'")}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z" />
|
||||
</svg>
|
||||
Watch Trailer
|
||||
</button>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
${movie.credits && movie.credits.cast && movie.credits.cast.length > 0 ? `
|
||||
<div class="cast-section">
|
||||
<h2 class="text-xl font-bold mb-4">Cast</h2>
|
||||
<div class="cast-list">
|
||||
${movie.credits.cast.slice(0, 8).map(person => `
|
||||
<div class="cast-item">
|
||||
<img
|
||||
src="${person.profile_path ? `https://image.tmdb.org/t/p/w185${person.profile_path}` : 'https://via.placeholder.com/80x80'}"
|
||||
alt="${person.name}"
|
||||
class="cast-image"
|
||||
onerror="this.src='https://via.placeholder.com/80x80?text=${encodeURIComponent(person.name[0])}'"
|
||||
>
|
||||
<div class="text-sm font-medium">${person.name}</div>
|
||||
<div class="text-xs text-gray-500">${person.character}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Add to the DOM
|
||||
document.body.appendChild(detailsModal);
|
||||
|
||||
// Add event listener to close button
|
||||
const closeBtn = detailsModal.querySelector('.details-close');
|
||||
closeBtn.addEventListener('click', () => {
|
||||
detailsModal.remove();
|
||||
});
|
||||
|
||||
// Close on click outside content
|
||||
detailsModal.addEventListener('click', (e) => {
|
||||
if (e.target === detailsModal) {
|
||||
detailsModal.remove();
|
||||
}
|
||||
});
|
||||
|
||||
showProgress('Details loaded');
|
||||
} catch (error) {
|
||||
console.error('Error loading movie details:', error);
|
||||
showProgress('Error loading details');
|
||||
}
|
||||
}
|
||||
|
||||
// Improved openModal function with season/episode selector
|
||||
async function openModal(mediaType, tmdbId, season = 1, episode = 1) {
|
||||
try {
|
||||
|
|
@ -800,8 +1235,8 @@
|
|||
videoUrl += `tv/${currentImdbId}/${currentSeason}/${currentEpisode}`;
|
||||
}
|
||||
} else {
|
||||
// vidsrc.xyz format - exactly as in the original code
|
||||
videoUrl = 'https://vidsrc.xyz/embed/';
|
||||
// vidsrc.xyz format - exactly as in the original code
|
||||
videoUrl = 'https://vidsrc.xyz/embed/';
|
||||
if (currentMediaType === 'movie') {
|
||||
videoUrl += `movie/${currentTmdbId}`;
|
||||
} else if (currentMediaType === 'tv') {
|
||||
|
|
@ -990,12 +1425,21 @@
|
|||
const rating = movie.vote_average ?
|
||||
`<div class="rating-badge">${movie.vote_average.toFixed(1)} ⭐</div>` : '';
|
||||
|
||||
// Enhanced movie card with info button
|
||||
movieCard.innerHTML = `
|
||||
<a href="javascript:void(0);" onclick="openModal('movie', '${movie.id}')">
|
||||
<div class="relative">
|
||||
<img src="https://image.tmdb.org/t/p/w342${movie.poster_path}" alt="${movie.title}" loading="lazy">
|
||||
${rating}
|
||||
<h3 class="text-sm font-medium mt-2">${movie.title}</h3>
|
||||
</a>
|
||||
</div>
|
||||
<h3 class="text-sm font-medium mt-2">${movie.title}</h3>
|
||||
<div class="flex justify-between mt-2">
|
||||
<button class="text-xs bg-green-500 hover:bg-green-600 text-white px-2 py-1 rounded" onclick="openModal('movie', ${movie.id})">
|
||||
Watch
|
||||
</button>
|
||||
<button class="text-xs bg-blue-500 hover:bg-blue-600 text-white px-2 py-1 rounded" onclick="openMovieDetails('movie', ${movie.id})">
|
||||
Details
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(movieCard);
|
||||
}
|
||||
|
|
@ -1047,51 +1491,52 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Function to setup all dynamic categories
|
||||
function setupCategories() {
|
||||
// Create category sections with placeholders first
|
||||
createCategorySection('💥 Action-Packed Thrills');
|
||||
createCategorySection('🏆 Critics\' Favorites');
|
||||
createCategorySection('🆕 Fresh Off The Press');
|
||||
createCategorySection('🍿 Crowd Pleasers');
|
||||
createCategorySection('👻 Spooky Stuff');
|
||||
createCategorySection('🦖 So Bad They\'re Extinct');
|
||||
createCategorySection('🧠 Movies That Make No Sense');
|
||||
createCategorySection('😴 Perfect For Napping');
|
||||
createCategorySection('🔪 Don\'t Watch Alone');
|
||||
createCategorySection('🌈 Movies Your Parents Hated');
|
||||
createCategorySection('🚗 Explosions Go Boom');
|
||||
createCategorySection('👽 Weird Stuff From Space');
|
||||
|
||||
// Fetch movies for each category
|
||||
fetchMoviesByGenre(genreMap.action, '💥 Action-Packed Thrills');
|
||||
fetchHighRatedMovies('🏆 Critics\' Favorites');
|
||||
fetchRecentReleases('🆕 Fresh Off The Press');
|
||||
fetchMoviesByGenre(genreMap.comedy, '🍿 Crowd Pleasers');
|
||||
fetchMoviesByGenre(genreMap.horror, '👻 Spooky Stuff');
|
||||
fetchMoviesByGenre(genreMap.western, '🦖 So Bad They\'re Extinct');
|
||||
fetchMoviesByGenre(genreMap.scienceFiction, '🧠 Movies That Make No Sense');
|
||||
fetchMoviesByGenre(genreMap.documentary, '😴 Perfect For Napping');
|
||||
fetchMoviesByGenre(genreMap.thriller, '🔪 Don\'t Watch Alone');
|
||||
fetchMoviesByGenre(genreMap.family, '🌈 Movies Your Parents Hated');
|
||||
fetchActionExplosionMovies('🚗 Explosions Go Boom');
|
||||
fetchMoviesByGenre(genreMap.scienceFiction, '👽 Weird Stuff From Space');
|
||||
}
|
||||
// Additional function to get action movies with high popularity
|
||||
function fetchActionExplosionMovies(categoryTitle) {
|
||||
const url = `https://api.themoviedb.org/3/discover/movie?api_key=${apiKey}&with_genres=${genreMap.action}&sort_by=popularity.desc&vote_count.gte=500`;
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
displayCategoryMovies(data.results, categoryTitle);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(`Error fetching explosion movies:`, error);
|
||||
showProgress(`Failed to load ${categoryTitle}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to setup all dynamic categories
|
||||
function setupCategories() {
|
||||
// Create category sections with placeholders first
|
||||
createCategorySection('💥 Action-Packed Thrills');
|
||||
createCategorySection('🏆 Critics\' Favorites');
|
||||
createCategorySection('🆕 Fresh Off The Press');
|
||||
createCategorySection('🍿 Crowd Pleasers');
|
||||
createCategorySection('👻 Spooky Stuff');
|
||||
createCategorySection('🦖 So Bad They\'re Extinct');
|
||||
createCategorySection('🧠 Movies That Make No Sense');
|
||||
createCategorySection('😴 Perfect For Napping');
|
||||
createCategorySection('🔪 Don\'t Watch Alone');
|
||||
createCategorySection('🌈 Movies Your Parents Hated');
|
||||
createCategorySection('🚗 Explosions Go Boom');
|
||||
createCategorySection('👽 Weird Stuff From Space');
|
||||
|
||||
// Fetch movies for each category
|
||||
fetchMoviesByGenre(genreMap.action, '💥 Action-Packed Thrills');
|
||||
fetchHighRatedMovies('🏆 Critics\' Favorites');
|
||||
fetchRecentReleases('🆕 Fresh Off The Press');
|
||||
fetchMoviesByGenre(genreMap.comedy, '🍿 Crowd Pleasers');
|
||||
fetchMoviesByGenre(genreMap.horror, '👻 Spooky Stuff');
|
||||
fetchMoviesByGenre(genreMap.western, '🦖 So Bad They\'re Extinct');
|
||||
fetchMoviesByGenre(genreMap.scienceFiction, '🧠 Movies That Make No Sense');
|
||||
fetchMoviesByGenre(genreMap.documentary, '😴 Perfect For Napping');
|
||||
fetchMoviesByGenre(genreMap.thriller, '🔪 Don\'t Watch Alone');
|
||||
fetchMoviesByGenre(genreMap.family, '🌈 Movies Your Parents Hated');
|
||||
fetchActionExplosionMovies('🚗 Explosions Go Boom');
|
||||
fetchMoviesByGenre(genreMap.scienceFiction, '👽 Weird Stuff From Space');
|
||||
}
|
||||
|
||||
// Additional function to get action movies with high popularity
|
||||
function fetchActionExplosionMovies(categoryTitle) {
|
||||
const url = `https://api.themoviedb.org/3/discover/movie?api_key=${apiKey}&with_genres=${genreMap.action}&sort_by=popularity.desc&vote_count.gte=500`;
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
displayCategoryMovies(data.results, categoryTitle);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(`Error fetching explosion movies:`, error);
|
||||
showProgress(`Failed to load ${categoryTitle}`);
|
||||
});
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Setup all categories
|
||||
setupCategories();
|
||||
|
|
@ -1105,9 +1550,25 @@ function fetchActionExplosionMovies(categoryTitle) {
|
|||
if (e.key === '/' && document.activeElement.tagName !== 'INPUT') {
|
||||
e.preventDefault();
|
||||
document.querySelector('[name="search"]').focus();
|
||||
} else if (e.key === 'Escape' && modal.style.display === 'block') {
|
||||
modal.style.display = "none";
|
||||
videoIframe.src = "";
|
||||
} else if (e.key === 'Escape') {
|
||||
// Close any open modals
|
||||
const videoModal = document.getElementById("videoModal");
|
||||
if (videoModal.style.display === 'block') {
|
||||
videoModal.style.display = "none";
|
||||
videoIframe.src = "";
|
||||
}
|
||||
|
||||
// Close any details modal
|
||||
const detailsModal = document.getElementById('movieDetailsModal');
|
||||
if (detailsModal) {
|
||||
detailsModal.remove();
|
||||
}
|
||||
|
||||
// Close any pip trailers
|
||||
const pipContainer = document.querySelector('.pip-container');
|
||||
if (pipContainer) {
|
||||
pipContainer.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -1147,10 +1608,15 @@ function fetchActionExplosionMovies(categoryTitle) {
|
|||
const movieCard = document.createElement('div');
|
||||
movieCard.className = 'slider-item';
|
||||
movieCard.innerHTML = `
|
||||
<a href="javascript:void(0);" onclick="openModal('movie', '${movie.id}')">
|
||||
<div class="relative">
|
||||
<img src="https://image.tmdb.org/t/p/w500${movie.poster_path}" alt="${movie.title}" class="rounded-lg w-full h-auto" loading="lazy">
|
||||
<h3 class="text-lg font-semibold mt-2">${movie.title}</h3>
|
||||
</a>
|
||||
${movie.vote_average ? `<div class="rating-badge">${movie.vote_average.toFixed(1)} ⭐</div>` : ''}
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold mt-2">${movie.title}</h3>
|
||||
<div class="flex justify-between mt-2">
|
||||
<button class="bg-green-500 hover:bg-green-600 text-white px-3 py-1 rounded text-sm" onclick="openModal('movie', '${movie.id}')">Watch</button>
|
||||
<button class="bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded text-sm" onclick="openMovieDetails('movie', ${movie.id})">Details</button>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(movieCard);
|
||||
}
|
||||
|
|
@ -1164,13 +1630,18 @@ function fetchActionExplosionMovies(categoryTitle) {
|
|||
if (movie.poster_path) {
|
||||
const movieTile = document.createElement('div');
|
||||
movieTile.className = 'movie-tile';
|
||||
|
||||
movieTile.innerHTML = `
|
||||
<a href="javascript:void(0);" onclick="openModal('movie', '${movie.id}')">
|
||||
<div class="relative">
|
||||
<img src="https://image.tmdb.org/t/p/w500${movie.poster_path}" alt="${movie.title}" class="rounded-lg w-full h-auto" loading="lazy">
|
||||
<h3>${movie.title}</h3>
|
||||
<p>${movie.overview ? movie.overview.substring(0, 100) + (movie.overview.length > 100 ? '...' : '') : 'No description available.'}</p>
|
||||
</a>
|
||||
<button class="trailer-btn" onclick="fetchTrailer('${movie.title}')">Trailer</button>
|
||||
${movie.vote_average ? `<div class="rating-badge">${movie.vote_average.toFixed(1)} ⭐</div>` : ''}
|
||||
</div>
|
||||
<h3>${movie.title}</h3>
|
||||
<p>${movie.overview ? movie.overview.substring(0, 100) + (movie.overview.length > 100 ? '...' : '') : 'No description available.'}</p>
|
||||
<div class="flex justify-between mt-3">
|
||||
<button class="bg-green-500 hover:bg-green-600 text-white px-3 py-1 rounded text-sm" onclick="openModal('movie', '${movie.id}')">Watch</button>
|
||||
<button class="bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded text-sm" onclick="openMovieDetails('movie', ${movie.id})">Details</button>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(movieTile);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue