I'm facing a challenge in my JavaScript/HTML project where I want to display only four videos in the 'Continue Watching' section without affecting other video cards on the page. The current implementation interferes with non-'Continue Watching' videos when I limit the display to four. Looking for guidance on resolving this issue.
https://e4171bb3-9e7c-4e1f-bfa9-093c7adb1510-00-2yr904r2mq889.spock.replit.dev
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="MelliePlay - A Better Version of YouTube"
/>
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="MelliePlay" />
<meta
property="og:description"
content="Discover and enjoy amazing content on MelliePlay."
/>
<meta property="og:image" content="url_to_thumbnail_image.jpg" />
<meta property="og:url" content="url_to_your_site" />
<!-- Google Font API -->
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=YourChosenFont:300,400,500"
/>
<!-- LottieFiles CDN -->
<script src="https://cdn.lottiefiles.com/5.7.8/lottie.js"></script>
<!-- XRegExp -->
<script src="https://unpkg.com/[email protected]/xregexp-all.js"></script>
<!-- Hammer.js -->
<script src="https://unpkg.com/[email protected]/hammer.min.js"></script>
<!-- Polymer Framework -->
<script
type="module"
src="https://unpkg.com/@polymer/[email protected]/lib/polymer-element.js"
></script>
<!-- Include other Polymer elements as needed -->
<link rel="stylesheet" href="style.css" />
<!-- Link to the external style.css file -->
<title>MelliePlay</title>
</head>
<body>
<!-- Top Bar -->
<div id="header">
<div id="menu-arrow" onclick="toggleSideMenu()">▶️</div>
<a id="logo" href="https://e4171bb3-9e7c-4e1f-bfa9-093c7adb1510-00-2yr904r2mq889.spock.replit.dev/">MelliePlay</a>
<div id="searchBox">
<input class="searchInput" type="text" name="" placeholder="Search" />
<button class="searchButton" href="#">
<i class="material-icons">🔎︎</i>
</button>
</div>
</div>
<div id="side-menu-overlay" onclick="closeSideMenu()">✖</div>
<div id="side-menu">
<div id="close-button" onclick="closeSideMenu()">✖</div>
<ul>
<li><a href="#">Home</a></li>
<li><a href="yourchannrl.html"><svg class="svg-icon" viewBox="0 0 20 20">
<path fill="none" d="M14.023,12.154c1.514-1.192,2.488-3.038,2.488-5.114c0-3.597-2.914-6.512-6.512-6.512
c-3.597,0-6.512,2.916-6.512,6.512c0,2.076,0.975,3.922,2.489,5.114c-2.714,1.385-4.625,4.117-4.836,7.318h1.186
c0.229-2.998,2.177-5.512,4.86-6.566c0.853,0.41,1.804,0.646,2.813,0.646c1.01,0,1.961-0.236,2.812-0.646
c2.684,1.055,4.633,3.568,4.859,6.566h1.188C18.648,16.271,16.736,13.539,14.023,12.154z M10,12.367
c-2.943,0-5.328-2.385-5.328-5.327c0-2.943,2.385-5.328,5.328-5.328c2.943,0,5.328,2.385,5.328,5.328
C15.328,9.982,12.943,12.367,10,12.367z"></path>
</svg> Your channel</a></li>
<li><a href="#">Item 3</a></li>
<li><a href="#">Item 4</a></li>
<li><a href="#">Item 5</a></li>
<!-- Add more items as needed -->
</ul>
</div>
<!-- Currently Playing Video -->
<div id="continue-watching">
<!-- Video Player Placeholder -->
<div id="video-player">Continue Watching:</div>
<!-- List of Last Four Videos -->
<div class="video-card" onclick="playVideo('video4')">
<img src="thumbnail0.jpg" alt="Video 4" class="video-thumbnail" />
<div class="video-details">
<div class="video-title">Video 4 Title</div>
<div class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<div class="video-card" onclick="playVideo('video3')">
<img src="thumbnail0.jpg" alt="Video 3" class="video-thumbnail" />
<div class="video-details">
<div class="video-title">Video 3 Title</div>
<div class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<div class="video-card" onclick="playVideo('video2')">
<img src="thumbnail0.jpg" alt="Video 2" class="video-thumbnail" />
<div class="video-details">
<div class="video-title">Video 2 Title</div>
<div class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<div class="video-card" onclick="playVideo('video1')">
<img src="thumbnail1.jpg" alt="Video 1" class="video-thumbnail" />
<div class="video-details">
<div class="video-title">Video 1 Title</div>
<div class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
</div>
<hr
style="
width: 100%;
margin: 0;
border: none;
height: 2px;
background-color: #ccc;
"
/>
<!-- Video Container -->
<div id="video-container">
<!-- Video Card 1 -->
<div class="video-card" onclick="playVideo('video1')" id="video-card-1">
<a href="watch.html?videoId=video1">
<img src="thumbnails/thumbnail1.jpg" alt="Video 1" id="video-thumbnail-video1" class="video-thumbnail"/>
<div class="video-details">
<div id="video-title-video1">Video Title Placeholder</div>
<div id="video-description-video1" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<!-- Video Card 2 -->
<div class="video-card" onclick="playVideo('video2')" id="video-card-2">
<a href="watch.html?videoId=video2">
<img src="thumbnails/thumbnail2.jpg" alt="Video 2" id="video-thumbnail-video2" class="video-thumbnail" />
<div class="video-details">
<div id="video-title-video2">Video Title Placeholder</div>
<div id="video-description-video2" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<!-- Video Card 3 -->
<div class="video-card" onclick="playVideo('video3')" id="video-card-3">
<a href="watch.html?videoId=video3">
<img src="thumbnails/thumbnail3.jpg" alt="Video 3" id="video-thumbnail-video3" class="video-thumbnail" />
<div class="video-details">
<div id="video-title-video3">Video Title Placeholder</div>
<div id="video-description-video3" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<!-- Video Card 4 -->
<div class="video-card" onclick="playVideo('video4')" id="video-card-4">
<a href="watch.html?videoId=video4">
<img src="thumbnails/thumbnail4.jpg" alt="Video 4" id="video-thumbnail-video4" class="video-thumbnail" />
<div class="video-details">
<div id="video-title-video4">Video Title Placeholder</div>
<div id="video-description-video4" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<!-- Video Card 5 -->
<div class="video-card" onclick="playVideo('video5')" id="video-card-5">
<a href="watch.html?videoId=video5">
<img src="thumbnails/thumbnail5.jpg" alt="Video 5" id="video-thumbnail-video5" class="video-thumbnail" />
<div class="video-details">
<div id="video-title-video5">Video Title Placeholder</div>
<div id="video-description-video5" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<!-- Video Card 6 -->
<div class="video-card" onclick="playVideo('video6')" id="video-card-6">
<a href="watch.html?videoId=video6">
<img src="thumbnails/thumbnail6.jpg" alt="Video 6" id="video-thumbnail-video6" class="video-thumbnail" />
<div class="video-details">
<div id="video-title-video6">Video Title Placeholder</div>
<div id="video-description-video6" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<!-- Video Card 7 -->
<div class="video-card" onclick="playVideo('video7')" id="video-card-7">
<a href="watch.html?videoId=video7">
<img src="thumbnails/thumbnail6.jpg" alt="Video 7" id="video-thumbnail-video7" class="video-thumbnail" />
<div class="video-details">
<div id="video-title-video7">Video Title Placeholder</div>
<div id="video-description-video7" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
<!-- Video Card 8 -->
<div class="video-card" onclick="playVideo('video8')" id="video-card-8">
<a href="watch.html?videoId=video8">
<img src="thumbnails/thumbnail6.jpg" alt="Video 8" id="video-thumbnail-video8" class="video-thumbnail" />
<div class="video-details">
<div id="video-title-video8">Video Title Placeholder</div>
<div id="video-description-video8" class="video-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
</div>
<script>
let loaded = false;
let currentPage = 1;
const videosPerPage = 4; // Display only 4 videos
let loadedVideos = [];
let lastWatchedVideos = [];
if (localStorage.getItem('lastWatchedVideos')) {
lastWatchedVideos = JSON.parse(localStorage.getItem('lastWatchedVideos'));
}
function setDefaultInfo(videoId) {
// Function to set default information if details are not available
const videoTitle = document.getElementById(`video-title-${videoId}`);
const videoDescription = document.getElementById(`video-description-${videoId}`);
const videoThumbnail = document.getElementById(`video-thumbnail-${videoId}`);
if (videoTitle && videoDescription && videoThumbnail) {
videoTitle.innerText = "No Title Found";
videoDescription.innerText = "No Description Found";
videoThumbnail.src = `images/thumbnails/${videoId}.jpg`;
videoThumbnail.alt = "Video Title";
videoThumbnail.className = "video-thumbnail";
console.log(`Default info set for video ${videoId}`);
}
}
function playVideo(videoId) {
if (!loaded) {
const videoPlayer = document.getElementById('video-player');
const videoTitle = document.getElementById(`video-title-${videoId}`);
const videoDescription = document.getElementById(`video-description-${videoId}`);
const videoThumbnail = document.getElementById(`video-thumbnail-${videoId}`);
if (videoPlayer && videoTitle && videoDescription && videoThumbnail) {
fetch(`details/${videoId}.json`)
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('Fetched data:', data);
const { title, description, thumbnail, videoSrc } = data;
if (videoSrc) {
videoPlayer.src = videoSrc;
}
videoTitle.innerText = title || 'No Title Found';
videoDescription.innerText = description || 'No Description Found';
videoThumbnail.src = thumbnail || `images/thumbnails/${videoId}.jpg`;
loaded = true;
})
.catch((error) => {
console.error('Error fetching video details:', error);
setDefaultInfo(videoId);
});
} else {
console.error(`One or more elements not found for video ${videoId}`);
}
} else {
console.log(`Video ${videoId} clicked or loaded.`);
}
// Add the following lines to track the last four videos
if (!lastWatchedVideos.includes(videoId)) {
lastWatchedVideos.unshift(videoId); // Add to the beginning of the array
if (lastWatchedVideos.length > 4) {
lastWatchedVideos.pop(); // Remove the oldest video if the array size exceeds four
}
// Save updated lastWatchedVideos to localStorage
localStorage.setItem('lastWatchedVideos', JSON.stringify(lastWatchedVideos));
}
// Update the "Continue Watching" section
updateContinueWatching();
}
function updateContinueWatching() {
const continueWatchingSection = document.getElementById('continue-watching');
continueWatchingSection.innerHTML = '<div id="video-player">Continue Watching:</div>';
// Display "No videos found" message if there are no last watched videos
if (lastWatchedVideos.length === 0) {
displayNoVideosMessage(continueWatchingSection);
return;
}
// Slice the last four videos from the array
const lastFourWatchedVideos = lastWatchedVideos.slice(0, 4);
lastFourWatchedVideos.forEach((videoId) => {
const videoCard = document.createElement('div');
videoCard.classList.add('video-card');
videoCard.onclick = () => playVideo(videoId);
// Fetch details and populate the card as per your existing logic
fetchVideoDetails(videoId).then((data) => {
// Update the card content using data from the fetch
// You can modify this part based on your existing logic
const { title, description, thumbnail } = data;
videoCard.innerHTML = `
<img src="${thumbnail || `images/thumbnails/${videoId}.jpg`}" alt="Video ${videoId}" class="video-thumbnail" />
<div class="video-details">
<div class="video-title">${title || 'No Title Found'}</div>
<div class="video-description">${description || 'No Description Found'}</div>
</div>
`;
continueWatchingSection.appendChild(videoCard);
});
});
}
// Function to fetch video details
function fetchVideoDetails(videoId) {
return fetch(`details/${videoId}.json`)
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.catch((error) => {
console.error('Error fetching video details:', error);
return {};
});
}
// Ensure that the lastWatchedVideos array is updated on page load
window.addEventListener('DOMContentLoaded', () => {
if (loadedVideos.length === 0) {
displayAllVideosMessage();
updateContinueWatching();
}
});
function loadVideos() {
for (let i = 1; i <= videosPerPage; i++) {
const videoIndex = (currentPage - 1) * videosPerPage + i;
if (!loadedVideos.includes(videoIndex)) {
playVideo(`video${videoIndex}`);
loadedVideos.push(videoIndex);
}
}
}
function handleScroll() {
const lastVideoCard = document.querySelector('.video-card:last-child');
const lastCardOffset = lastVideoCard.offsetTop + lastVideoCard.clientHeight;
const pageOffset = window.pageYOffset + window.innerHeight;
if (pageOffset > lastCardOffset - 100 && !loaded) {
loaded = true;
loadVideos();
currentPage++;
}
}
function displayAllVideosMessage() {
const videoContainer = document.getElementById('video-container');
const message = document.createElement('p');
message.innerText = 'All videos in our database are loaded! :p';
videoContainer.appendChild(message);
}
// Check if all videos are loaded and display a message
window.addEventListener('DOMContentLoaded', () => {
if (loadedVideos.length === 0) {
displayAllVideosMessage();
}
});
function toggleSideMenu() {
const sideMenuOverlay = document.getElementById('side-menu-overlay');
const sideMenu = document.getElementById('side-menu');
if (sideMenuOverlay.style.display === 'block' || sideMenu.style.display === 'block') {
sideMenuOverlay.style.display = 'none';
sideMenu.style.display = 'none';
} else {
sideMenuOverlay.style.display = 'block';
sideMenu.style.display = 'block';
}
}
function closeSideMenu() {
const sideMenuOverlay = document.getElementById('side-menu-overlay');
const sideMenu = document.getElementById('side-menu');
sideMenuOverlay.style.display = 'none';
sideMenu.style.display = 'none';
}
function displayNoVideosMessage(continueWatchingSection) {
const message = document.createElement('p');
message.innerText = 'No videos found!';
continueWatchingSection.appendChild(message);
}
// Initial load of videos
loadVideos();
// Add scroll event listener
window.addEventListener('scroll', handleScroll);
</script>
</body>
</html>
I attempted to modify the JavaScript code to limit the 'Continue Watching' section to display only four videos. I expected that this change would not interfere with the display of other non-'Continue Watching' video cards. However, the issue persists, and the adjustment seems to impact other video cards on the page. I just found out when i click on the 'Continue Watching' section it's then show 4 rather then 21 but the videos cards under it only show 4/8 which i dont want!
The issue was caused by the loop that created and appended four video cards for the last four watched videos, including empty placeholders. The fix involved modifying the
updateContinueWatchingfunction to create only one video card for the last watched video and display it without any empty placeholders.Here's a breakdown of the changes:
Removed the loop that created four video cards and empty placeholders:
This loop was replaced with a single video card creation for the last watched video:
Removed the loop that added empty placeholders separately:
This loop was removed as it's not needed when we are displaying only one video card for the last watched video.
By making these changes, we ensure that only one video card is created for the last watched video, and no empty placeholders are added.